Daily Creative Coding

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

形成と崩壊

/**
* Formation And Collapseß 
*
* @author aa_debdeb
* @date 2016/02/22
*/

int state;
ArrayList<Block> blocks;

void setup(){
  size(500, 500);
  frameRate(60);
  stroke(230, 200);
  fill(192, 200);
  state = 0;
}

void draw(){
  if(state == 0){
    initialize();
    state = 1;
  }
  if(state == 1){
    background(153, 14, 42);
    for(Block block : blocks){
      block.display();
      block.update(state);
    }
    boolean allReached = true;
    for(Block block : blocks){
      if(!block.isReached()){
        allReached = false;
        break;
      }
    }
    if(allReached){
      state = 2;
      for(Block block : blocks){
        float velAng = map(random(1), 0, 1, PI, TWO_PI);
        block.vel = new PVector(3 * cos(velAng), 3 * sin(velAng));
      }
    }
  } else if(state == 2){
    background(153, 14, 42);
    for(Block block : blocks){
      block.display();
      block.update(state);
    } 
    boolean allDroped = true;
    for(Block block : blocks){
      if(!block.isDroped()){
        allDroped = false;
        break;
      }
    }
    if(allDroped){
      state = 0;
    }
  }
}

void initialize(){
  blocks = new ArrayList<Block>();
  for(int h = 0; h < 20; h++){
    for(int w = 0; w < 20; w++){
      float x = 50 + w * 20;
      float y = 50 + h * 20;
      PVector targetPos = new PVector(x, y);
      blocks.add(new Block(targetPos, 20));
    }
  }
}

class Block {

  PVector pos, targetPos;
  PVector vel;
  float size;
  
  Block(PVector targetPos, float size){
    pos = new PVector(1, 1);
    while(-50 <= pos.x && pos.x < width + 50 && -50 <= pos.y && pos.y < height + 50){
      float x = map(random(1), 0, 1, -100, width + 100);
      float y = map(random(1), 0, 1, -100, height + 100);
      pos = new PVector(x, y);
    }
    this.targetPos = targetPos;
    this.size = size;
  }
  
  void update(int state){
    if(state == 1){
      vel = PVector.sub(targetPos, pos);
      vel.limit(3);
      pos.add(vel);
    } else if(state == 2){
      vel.add(new PVector(0, 0.1));
      pos.add(vel);  
    }
  }
  
  void display(){
    rect(pos.x, pos.y, size, size);
  }
  
  boolean isReached(){
    if(PVector.dist(pos, targetPos) < 0.1){
      return true;
    } else {
      return false;
    }
  }
  
  boolean isDroped(){
    if(pos.y > height){
      return true;
    } else {
      return false;
    }
  }
  
}