Skip to content

Commit

Permalink
Add new targetting mechanics
Browse files Browse the repository at this point in the history
new system that couple of targets will be set and fireflies will go to target(s)
  • Loading branch information
pouyamer committed Apr 23, 2024
1 parent 0dc84c4 commit f72bc33
Show file tree
Hide file tree
Showing 10 changed files with 317 additions and 7 deletions.
181 changes: 177 additions & 4 deletions src/Classes/firefly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,19 @@ class FireFly {
size: 0,
sizeBehaviourWhenFading: "none",
sizeBehaviourWhenGlowing: "none",
speedPolar: 0,
accelerationPolar: 0,
speedX: 0,
speedY: 0,
accelerationX: 0,
accelerationY: 0,
quarterCircleCenterLocation: "bottom-left",
wind: new Wind(windConfig),
windResistance: 0,
windAffectStrength: 0
windAffectStrength: 0,
willFollowTarget: false,
targets: [],
currentTarget: new Target(0, 0, [])
}

this.config = this.initializedConfig
Expand Down Expand Up @@ -146,6 +151,8 @@ class FireFly {
rotationAcceleration:
this.utilGetRandomNumberBetween(rotationAcceleration) /
iterationsPerFrame,
accelerationPolar:
this.utilGetRandomNumberBetween(accelerationPolar) / iterationsPerFrame,
accelerationX:
this.determinePropertyXonCartesianOrPolar(
accelerationX,
Expand Down Expand Up @@ -196,6 +203,8 @@ class FireFly {
opacityChangeMode,
// size gets randomized based on your config
size: fireflySize,
speedPolar:
this.utilGetRandomNumberBetween(speedPolar) / iterationsPerFrame,
speedX:
this.determinePropertyXonCartesianOrPolar(
speedX,
Expand All @@ -215,7 +224,12 @@ class FireFly {
quarterCircleCenterLocation: getQuarterCircleCenterLocation(),
wind: new Wind(windConfig),
windResistance: 0,
windAffectStrength: 0
windAffectStrength: 0,
willFollowTarget:
appConfig.target.toggle &&
Math.random() < appConfig.target.followChance,
targets: [],
currentTarget: new Target(0, 0, [])
}

const { x: startingX, y: startingY } = this.getNewPosition(
Expand All @@ -236,6 +250,69 @@ class FireFly {
}
}

addTargets(targets: Target[]) {
for (const target of targets) {
this.config.targets.push(target)
}
}

utilCalculateDistance = (x1: number, y1: number, x2: number, y2: number) => {
return Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
}

pickCurrentTarget() {
switch (this.appConfig.target.targetPickingMethod) {
case "nearest":
let min = Infinity
for (const target of this.config.targets) {
const distanceToTarget = this.utilCalculateDistance(
target.x,
target.y,
this.config.x,
this.config.y
)

if (distanceToTarget < min) {
min = distanceToTarget
this.config.currentTarget = target
}
}

break

case "farthest":
let max = 0
for (const target of this.config.targets) {
const distanceToTarget = this.utilCalculateDistance(
target.x,
target.y,
this.config.x,
this.config.y
)

if (distanceToTarget > max) {
max = distanceToTarget
this.config.currentTarget = target
}
}
break

case "random":
this.config.currentTarget =
this.config.targets[
this.utilGetRandomNumberBetween(
{
min: 0,
max: this.config.targets.length - 1
},
true
)
]

break
}
}

debugLogger = (message: string) => {
if (this.config.debugMode) {
console.log(`[DEBUG] - ${message}`)
Expand Down Expand Up @@ -764,6 +841,9 @@ class FireFly {

this.config.rotationSpeed =
this.originalConfig.rotationSpeed / iterationsPerFrame

// recalculate the nearest target after opacitychange
this.pickCurrentTarget()
}

somewhereOverTheRainbow = () => {
Expand Down Expand Up @@ -1123,6 +1203,84 @@ class FireFly {
}
}

handleSmoothMoveToTarget = () => {
const angleBetweenBallAndTarget = Math.atan2(
this.config.currentTarget.y - this.config.y,
this.config.currentTarget.x - this.config.x
)

this.config.x +=
Math.cos(angleBetweenBallAndTarget) * this.config.speedPolar
this.config.y +=
Math.sin(angleBetweenBallAndTarget) * this.config.speedPolar
}

handleStiffMoveToTarget = () => {
const { x: targetX, y: targetY } = this.config.currentTarget

if (this.config.x < targetX) {
this.config.x += Math.abs(this.config.speedX)
}
if (this.config.x > targetX) {
this.config.x -= Math.abs(this.config.speedX)
}
if (this.config.y < targetY) {
this.config.y += Math.abs(this.config.speedY)
}
if (this.config.y > targetY) {
this.config.y -= Math.abs(this.config.speedY)
}
}

handleRandomMoveToTarget = () => {
const { x: targetX, y: targetY } = this.config.currentTarget

const pickMode = this.utilGetRandomNumberBetween({ min: 0, max: 2 }, true)

const checkXFromLeft = () => {
if (this.config.x < targetX) {
this.config.x += Math.abs(this.config.speedX)
}
}

const checkXFromRight = () => {
if (this.config.x > targetX) {
this.config.x -= Math.abs(this.config.speedX)
}
}

const checkYFromTop = () => {
if (this.config.y < targetY) {
this.config.y += Math.abs(this.config.speedY)
}
}

const checkYFromBottom = () => {
if (this.config.y > targetY) {
this.config.y -= Math.abs(this.config.speedY)
}
}

if (Math.random() < this.appConfig.target.randomMovementChance) {
switch (pickMode) {
case 0:
checkXFromLeft()
checkXFromRight()
break
case 1:
checkYFromBottom()
checkYFromTop
break
case 2:
checkXFromLeft()
checkXFromRight()
checkYFromBottom()
checkYFromTop()
break
}
}
}

update(ctx: CanvasRenderingContext2D, hueShiftAmount: number) {
this.draw(ctx, hueShiftAmount)
this.handleRotation()
Expand All @@ -1134,8 +1292,23 @@ class FireFly {

// this.handleWind()

this.handleMove()
this.handleAcceleration()
if (this.config.willFollowTarget) {
switch (this.appConfig.target.movementsTowardsTargetMode) {
case "smooth":
this.handleSmoothMoveToTarget()
break
case "stiff":
this.handleStiffMoveToTarget()
break
default:
this.handleRandomMoveToTarget()
break
}
} else {
this.handleMove()
this.handleAcceleration()
}

this.handleJitter()

this.handleBoundsPositioning()
Expand Down
11 changes: 11 additions & 0 deletions src/Classes/target.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Target {
x: number
y: number
affectedFireflies: FireFly[]

constructor(x: number, y: number, affectedFireflies: FireFly[]) {
this.x = x
this.y = y
this.affectedFireflies = affectedFireflies
}
}
9 changes: 9 additions & 0 deletions src/Config/targetsConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const targetConfig: TargetConfigType = {
toggle: true,
count: 1,
followChance: 1,
movementsTowardsTargetMode: "smooth",
randomMovementChance: 1,
targetResetTime_MS: 3000,
targetPickingMethod: "nearest"
}
15 changes: 15 additions & 0 deletions src/Interfaces/ISingleFireflyConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,30 @@ interface ISingleFireflyConfig {
// Shape of the firefly
shape: ShapeType

// will the firefly follow the target?
willFollowTarget: boolean

// all the targets on the canvas
targets: Target[]

// the chosen target
currentTarget: Target

// if it's a polygon or square how many sides
sideCount: number
movementMode: MovementModeType
movingAngle: number
// Speed in which firefly moves
// - polar system*
speedPolar: number
// - Horizontally
speedX: number
// - Vertically
speedY: number

// Rate in which the speed changes:
// - polar system*
accelerationPolar: number
// - Horizontally
accelerationX: number
// - Vertically
Expand Down Expand Up @@ -71,3 +84,5 @@ interface ISingleFireflyConfig {
// EXPERIMENTAL: how much firefly is affected by wind [0-1]
windAffectStrength: number
}

// *: Polar system is only determined for target movement
4 changes: 4 additions & 0 deletions src/Types/ConfigType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ type ConfigType = {
// wind affects all the fireflies
wind: WindConfigType

// targets are coordinates on the canvas that (some) points
// would start to follow
target: TargetConfigType

// this is a genearal config for all fireflies
// it is used to pick the config for each
// individual firefly later on
Expand Down
6 changes: 6 additions & 0 deletions src/Types/MovementsTowardsTargetModesType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// modes of how a firefly should follow the target
// smooth : it moves with angle toward the target
// stiff: it moves based on the target's x and y position
// random: like stiff but the x and directions are picked
// one at a time on random
type MovementsTowardsTargetModesType = "smooth" | "stiff" | "random"
21 changes: 21 additions & 0 deletions src/Types/TargetConfigType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// target is coordinates on the canvas that
// (some) points
type TargetConfigType = {
// toggles whether the target feature is on or off
toggle: boolean
// how many targets are on the screen at once
count: number
// how long the target will stay on the screen
// until it resets
targetResetTime_MS: number
// likelihood that a firefly would follow
// targets [0 - 1]
followChance: number
// movement towards the target (smooth, stiff, random)
movementsTowardsTargetMode: MovementsTowardsTargetModesType
// if movementsTowardsTargetMode: random, then how much will firefly
// commit to move at all [0: won't move, 1: will totally move]
randomMovementChance: number
// How a target gets selected
targetPickingMethod: TargetPickingMethodType
}
1 change: 1 addition & 0 deletions src/Types/TargetPickingMethodType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type TargetPickingMethodType = "nearest" | "farthest" | "random"
7 changes: 4 additions & 3 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ const config: ConfigType = {
},
iterationsPerFrame: 3,
wind: windConfig,
target: targetConfig,

fireflies: {
count: 500,
count: 1000,

size: {
min: 20,
max: 30
min: 2,
max: 10
},

movement: movementConfig,
Expand Down
Loading

0 comments on commit f72bc33

Please sign in to comment.