Daily Creative Coding

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

サイバーな花火

/**
* cyber firework
*
* @author aa_debdeb
* @date 2016/08/24
*/

ArrayList<Beam> beams;

void setup(){
  size(800, 800, P3D);
  colorMode(HSB, 360, 100, 100);
  beams = new ArrayList<Beam>();
}

void mousePressed(){
  explode();
}

void keyPressed(){
  explode();
}

void explode(){
  float r = map(sqrt(random(1)), 0, 1, 0, 250);
  float a1 = random(PI);
  float a2 = random(TWO_PI);
  float x = r * sin(a1) * cos(a2);
  float y = r * cos(a1);
  float z = r * sin(a1) * sin(a2);
  color c = color(random(360), 100, 100);
  int num = int(random(50, 100));
  for(int i = 0; i < num; i++){
    beams.add(new Beam(x, y, z, c));
  }
}

void draw(){
  background(0, 100, 0);
  translate(width / 2, height / 2);
  rotateX(frameCount * 0.002);
  rotateY(frameCount * 0.003);
  rotateZ(frameCount * 0.005);
  ArrayList<Beam> nextBeams = new ArrayList<Beam>();
  for(Beam b: beams){
    b.display();
    b.update();
    if(!b.isDead()){
      nextBeams.add(b);
    }
  }
  beams = nextBeams;
}

class Beam{
    
  PVector end1, end2, vel;
  float span;
  int life;
  color col;
  
  Beam(float x, float y, float z, color c){
    end1 = new PVector(x, y, z);
    end2 = new PVector(x, y, z);
    vel = new PVector(random(-1, 1), random(-1, 1), random(-1, 1));
    vel.normalize();
    float velSize = random(2, 10);
    vel.mult(velSize);
    span = random(30, 60);
    life = int(random(50, 200));
    col = c; 
  }
  
  void display(){
    stroke(col);
    line(end1.x, end1.y, end1.z,  end2.x, end2.y, end2.z);
  } 
  
  void update(){
    if(life > 0){
      if(PVector.dist(end1, end2) < span){
        end1.add(vel);
      } else {
        end1.add(vel);
        end2.add(vel);
      }
      life--;
    } else {
      end2.add(vel);
    }
  }
  
  boolean isDead(){
    return life == 0 && PVector.dist(end1, end2) <= vel.mag();
  }
  
}
f:id:aa_debdeb:20160819183311j:plain