2020-05-04 15:17:55 +00:00
|
|
|
|
import Vector from './vector.mjs';
|
|
|
|
|
|
2020-05-04 16:17:25 +00:00
|
|
|
|
const meanPos = new Vector(0, 0);
|
|
|
|
|
const meanVel = new Vector(0, 0);
|
|
|
|
|
const repelForce = new Vector(0, 0);
|
2020-05-04 15:17:55 +00:00
|
|
|
|
|
|
|
|
|
export const update = (boids, params, time) =>
|
|
|
|
|
{
|
2020-05-04 16:17:25 +00:00
|
|
|
|
const boidsSize = boids.length;
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < boidsSize; ++i)
|
2020-05-04 15:17:55 +00:00
|
|
|
|
{
|
2020-05-04 16:17:25 +00:00
|
|
|
|
const me = boids[i];
|
2020-05-04 15:17:55 +00:00
|
|
|
|
|
2020-05-04 16:17:25 +00:00
|
|
|
|
meanPos.reset();
|
|
|
|
|
meanVel.reset();
|
|
|
|
|
repelForce.reset();
|
|
|
|
|
|
|
|
|
|
let visibleSize = 0;
|
2020-05-04 15:17:55 +00:00
|
|
|
|
|
2020-05-04 16:17:25 +00:00
|
|
|
|
for (let j = 0; j < boidsSize; ++j)
|
2020-05-04 15:17:55 +00:00
|
|
|
|
{
|
2020-05-04 16:17:25 +00:00
|
|
|
|
if (i != j)
|
|
|
|
|
{
|
|
|
|
|
const you = boids[j];
|
|
|
|
|
const dist = Vector.distSquared(me.pos, you.pos);
|
|
|
|
|
|
|
|
|
|
if (dist < params.visibleDist * params.visibleDist)
|
|
|
|
|
{
|
|
|
|
|
meanPos.add(you.pos);
|
|
|
|
|
meanVel.add(you.vel);
|
|
|
|
|
visibleSize += 1;
|
|
|
|
|
|
|
|
|
|
if (dist < params.closeDist * params.closeDist)
|
|
|
|
|
{
|
|
|
|
|
repelForce.add(me.pos).sub(you.pos);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-04 15:17:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-04 16:17:25 +00:00
|
|
|
|
// Attract towards center of visible flock
|
|
|
|
|
if (visibleSize >= 1)
|
2020-05-04 15:17:55 +00:00
|
|
|
|
{
|
2020-05-04 16:17:25 +00:00
|
|
|
|
me.vel.add(meanPos.div(visibleSize)
|
|
|
|
|
.sub(me.pos)
|
|
|
|
|
.mul(params.centerAccel));
|
2020-05-04 15:17:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Attract toward center of screen
|
2020-05-04 16:17:25 +00:00
|
|
|
|
me.vel.addMul(me.pos, -0.01);
|
2020-05-04 15:17:55 +00:00
|
|
|
|
|
|
|
|
|
// Repel away from close boids
|
2020-05-04 16:17:25 +00:00
|
|
|
|
me.vel.add(repelForce.mul(params.repelAccel));
|
2020-05-04 15:17:55 +00:00
|
|
|
|
|
|
|
|
|
// Match other boids’ velocity
|
2020-05-04 16:17:25 +00:00
|
|
|
|
if (visibleSize >= 1)
|
2020-05-04 15:17:55 +00:00
|
|
|
|
{
|
2020-05-04 16:17:25 +00:00
|
|
|
|
me.vel.add(meanVel.div(visibleSize)
|
|
|
|
|
.sub(me.vel)
|
|
|
|
|
.mul(params.matchAccel));
|
2020-05-04 15:17:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Do not surpass maximum speed
|
2020-05-04 16:17:25 +00:00
|
|
|
|
const speed = me.vel.normSquared();
|
2020-05-04 15:17:55 +00:00
|
|
|
|
|
|
|
|
|
if (speed > params.maxSpeed * params.maxSpeed)
|
|
|
|
|
{
|
2020-05-04 16:17:25 +00:00
|
|
|
|
me.vel.div(Math.sqrt(speed)).mul(params.maxSpeed);
|
2020-05-04 15:17:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-04 16:17:25 +00:00
|
|
|
|
// Integrate speed
|
|
|
|
|
me.pos.addMul(me.vel, time);
|
2020-05-04 15:17:55 +00:00
|
|
|
|
}
|
|
|
|
|
};
|