80 lines
2.1 KiB
JavaScript
80 lines
2.1 KiB
JavaScript
import Vector from './vector.mjs';
|
||
|
||
const meanPos = new Vector(0, 0);
|
||
const meanVel = new Vector(0, 0);
|
||
const repelForce = new Vector(0, 0);
|
||
|
||
export const update = (boids, params, width, height, time) =>
|
||
{
|
||
const boidsSize = boids.length;
|
||
|
||
for (let i = 0; i < boidsSize; ++i)
|
||
{
|
||
const me = boids[i];
|
||
|
||
meanPos.reset();
|
||
meanVel.reset();
|
||
repelForce.reset();
|
||
|
||
let visibleSize = 0;
|
||
|
||
for (let j = 0; j < boidsSize; ++j)
|
||
{
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Attract towards center of visible flock
|
||
if (visibleSize >= 1)
|
||
{
|
||
me.vel.add(meanPos.div(visibleSize)
|
||
.sub(me.pos)
|
||
.mul(params.centerAccel));
|
||
}
|
||
|
||
// Attract toward center of screen if out of bounds
|
||
if (me.pos.x < width * -.4 || me.pos.x > width * .4 ||
|
||
me.pos.y < height * -.4 || me.pos.y > height * .4)
|
||
{
|
||
me.vel.addMul(me.pos, -params.boundsAccel);
|
||
}
|
||
|
||
// Repel away from close boids
|
||
me.vel.add(repelForce.mul(params.repelAccel));
|
||
|
||
// Match other boids’ velocity
|
||
if (visibleSize >= 1)
|
||
{
|
||
me.vel.add(meanVel.div(visibleSize)
|
||
.sub(me.vel)
|
||
.mul(params.matchAccel));
|
||
}
|
||
|
||
// Do not surpass maximum speed
|
||
const speed = me.vel.normSquared();
|
||
|
||
if (speed > params.maxSpeed * params.maxSpeed)
|
||
{
|
||
me.vel.div(Math.sqrt(speed)).mul(params.maxSpeed);
|
||
}
|
||
|
||
// Integrate speed
|
||
me.pos.addMul(me.vel, time);
|
||
}
|
||
};
|