float MAX_ACC = 0.05;
float MAX_POSVEL = 4.0;
float MAX_BEZ_SPD = PI / 12;
float VELVARIANT_SIZE = 0.1;
float IMPACT_SIZE = 5.0;
ArrayList<Swimmer> swimmers;
void setup(){
size(500, 500);
smooth();
frameRate(60);
swimmers = new ArrayList<Swimmer>();
for(int i = 0; i < 200; i++){
swimmers.add(new Swimmer());
}
}
void draw(){
background(255, 192, 203);
for(Swimmer swimmer: swimmers){
swimmer.update();
swimmer.display();
}
}
void mousePressed(){
for(Swimmer swimmer: swimmers){
swimmer.impact();
}
}
class Swimmer{
PVector pos;
float bezierRad;
PVector vel;
PVector posVel;
float bezierSpeed;
Swimmer(){
pos = new PVector(random(width), random(height));
vel = new PVector(map(random(1), 0, 1, -1, 1), map(random(1), 0, 1, -1, 1));
vel.limit(1);
}
void update(){
PVector mouse = new PVector(mouseX, mouseY);
PVector dir = PVector.sub(mouse, pos);
dir.normalize();
PVector acc = PVector.mult(dir, MAX_ACC);
vel.add(acc);
PVector velVariant = new PVector(random(2) - 1, random(2) - 1);
velVariant.normalize();
velVariant.mult(VELVARIANT_SIZE);
vel.add(velVariant);
vel.limit(1);
posVel = PVector.mult(vel, MAX_POSVEL);
bezierSpeed = vel.mag() * MAX_BEZ_SPD;
pos.add(posVel);
if(pos.x < 0){pos.x += width;}
if(pos.x > width - 1){pos.x -= width;}
if(pos.y < 0){pos.y += height;}
if(pos.y > height - 1){pos.y -= height;}
bezierRad += bezierSpeed;
}
void impact(){
vel = new PVector(random(2) - 1, random(2) - 1);
vel.normalize();
vel.mult(IMPACT_SIZE);
}
void display(){
noFill();
stroke(255, 250, 240);
strokeWeight(4);
pushMatrix();
translate(pos.x, pos.y);
rotate(atan(vel.y / vel.x));
bezier(-15, 0,
-5, sin(bezierRad) * 10,
5, -sin(bezierRad) * 10,
15, 0);
popMatrix();
}
}