Daily Creative Coding

元「30 min. Processing」。毎日、Creative Codingします。

マウスに向かって泳ぐパーティクル

/**
* Swimmer to Mouse
*
* @author aa_debdeb
* @date 2016/01/03
*/

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)); 
//    rotate(vel.heading());
    bezier(-15, 0,
           -5, sin(bezierRad) * 10,
           5, -sin(bezierRad) * 10,
           15, 0); 
    popMatrix();
  }
  
}