xxxxxxxxxx
171
let bg; // Background image variable
let WALKER_COUNT = 20; // Number of walkers
let walkers = []; // Array of walkers
let ripples = []; // Store active ripples
let cohesionFactor = 0.01;
let separationFactor = 3;
let alignmentFactor = 0.001;
let neighborDist = 200;
function preload() {
bg = loadImage('color-01.png');
}
class Ripple {
constructor(x, y) {
this.x = x;
this.y = y;
this.diameter = 100;
this.alpha = 255;
this.isFinished = false;
}
update() {
this.diameter += 10;
this.alpha -= 3;
if (this.alpha <= 0) {
this.isFinished = true;
}
}
show() {
noFill();
stroke(100, 140, 149, this.alpha);
circle(this.x, this.y, this.diameter);
}
}
class Walker {
constructor() {
this.position = createVector(width / 2 + random(-100, 100), height / 2 + random(-100, 100));
this.velocity = p5.Vector.random2D();
this.acceleration = createVector(0, 0);
this.maxSpeed = 2;
this.stepCount = 0;
}
applyBehaviors(walkers) {
let cohesion = this.cohesion(walkers);
let separation = this.separation(walkers);
let alignment = this.alignment(walkers);
let followMouse = this.followMouse();
cohesion.mult(cohesionFactor);
separation.mult(separationFactor);
alignment.mult(alignmentFactor);
followMouse.mult(0.1);
this.acceleration.add(cohesion);
this.acceleration.add(separation);
this.acceleration.add(alignment);
this.acceleration.add(followMouse);
}
followMouse() {
let mouse = createVector(mouseX, mouseY);
let dir = p5.Vector.sub(mouse, this.position);
dir.normalize();
return dir;
}
cohesion(walkers) {
let sum = createVector(0, 0);
let count = 0;
for (let other of walkers) {
let d = dist(this.position.x, this.position.y, other.position.x, other.position.y);
if (d > 0 && d < neighborDist) {
sum.add(other.position);
count++;
}
}
if (count > 0) {
sum.div(count);
return p5.Vector.sub(sum, this.position).normalize();
}
return createVector(0, 0);
}
separation(walkers) {
let steer = createVector(0, 0);
let count = 0;
for (let other of walkers) {
let d = dist(this.position.x, this.position.y, other.position.x, other.position.y);
if (d > 0 && d < neighborDist / 2) {
let diff = p5.Vector.sub(this.position, other.position);
diff.normalize();
diff.div(d);
steer.add(diff);
count++;
}
}
if (count > 0) {
steer.div(count);
}
return steer;
}
alignment(walkers) {
let sum = createVector(0, 0);
let count = 0;
for (let other of walkers) {
let d = dist(this.position.x, this.position.y, other.position.x, other.position.y);
if (d > 0 && d < neighborDist) {
sum.add(other.velocity);
count++;
}
}
if (count > 0) {
sum.div(count);
sum.normalize();
return sum;
}
return createVector(0, 0);
}
update() {
this.velocity.add(this.acceleration);
this.velocity.limit(this.maxSpeed);
this.position.add(this.velocity);
this.acceleration.mult(0);
}
show() {
stroke(135, 25, 25);
point(this.position.x, this.position.y);
}
step(walkers) {
this.applyBehaviors(walkers);
this.update();
this.stepCount++;
return this.stepCount % 40 === 0;
}
}
function setup() {
createCanvas(1080 / 3, 1920 / 3);
for (let i = 0; i < WALKER_COUNT; i++) {
walkers.push(new Walker());
}
}
function draw() {
background(200, 213, 216, 60);
for (let i = ripples.length - 1; i >= 0; i--) {
ripples[i].update();
ripples[i].show();
if (ripples[i].isFinished) {
ripples.splice(i, 1);
}
}
for (let walker of walkers) {
if (walker.step(walkers)) {
ripples.push(new Ripple(walker.position.x, walker.position.y));
}
walker.show();
}
}