const playerRadius = 120;
pos: createVector(mouseX - width / 2, mouseY - height / 2),
createCanvas(720, 720, WEBGL);
colorMode(HSB, 360, 360, 360);
[particles, worms] = makeParticles();
directionalLight(color("white"), 0, 0, -1);
directionalLight(color(64), 0, 0, -1);
worms.forEach((e) => e.moveHead());
worms.forEach((e) => e.seek());
particles.forEach((e) => e.update());
particles.forEach((e) => e.wrap());
worms.forEach((e) => e.show());
function makeParticles() {
for (let i = 0; i < wormCount; i++) {
const hsbColor = (360 * i) / wormCount;
for (let j = 0; j < wormLength; j++) {
worms.push(new worm(group, hsbColor));
function mutualRepulsion() {
const all = particles.concat(player);
for (let i = all.length; i--; ) {
const delta = current.pos.copy().sub(target.pos);
const distance = delta.mag();
const sumRadii = current.radius + target.radius;
if (distance < sumRadii) {
const multi = pow(2, -distance / 4);
const force = delta.mult(multi);
current.radius == playerRadius && force.mult(10000);
function worm(arrayOfParticles, hsbColor) {
this.parts = arrayOfParticles;
this.color = color(hsbColor, 360, 360);
this.direction = random(2 * PI);
this.rotation = random(2) < 1 ? -0.01 : 0.01;
const head = this.parts[0];
this.direction += this.rotation;
const unitVector = createVector(1, 0).rotate(this.direction);
head.vel.add(unitVector);
for (let i = 1; i < this.parts.length; i++) {
const current = this.parts[i];
const prev = this.parts[i - 1];
const delta = current.pos.copy().sub(prev.pos);
const distance = delta.mag();
k = pow(1.25, -(distance / 10));
const force = delta.mult(k * 0.2);
let a = atan2(p.vel.y, p.vel.x);
this.pos = createVector(0, 0);
this.vel = createVector(0, 0);
const angle = random(PI * 2);
this.acc = createVector(1, 0).rotate(angle);
this.radius = random(minRadius, maxRadius);
this.vel.limit(speedLimit);
const r = this.radius + margin;
if (this.pos.x < r - width / 2 || this.pos.x > width / 2 - r) {
if (this.pos.y < r - height / 2 || this.pos.y > height / 2 - r) {