日常の進捗

主に自分のための,行為とその習慣化の記録

#Codevember day15: Fire

なんとなくフィーリングで書けるなとおもったら,過去書いたCoding Trainのアルゴリズムを思いっきり踏襲していた. 風や消滅の処理を,もうちょっとエレガントに書けるようになっておきたい.

//inspired by https://thecodingtrain.com/CodingChallenges/078-simple-particle-system.html

particles = [];
let wind;
function setup() {
  createCanvas(windowWidth, windowHeight);
    blendMode(ADD);
    
  colorMode(HSB,360,100,100,100);
  background(0);
}

function draw() {
    blendMode(NORMAL);
  background(0);
    blendMode(ADD);
  
  let n = noise(frameCount/100);
  n = map(n,0,1,5,10);  
    
    let wind = map(mouseX,0,height,1,-1);
    
  for (let i = 0; i < n; i++) {
    let p = new Particle();
    particles.push(p);
  }
  for (let i = particles.length - 1; i >= 0; i--) {
    particles[i].applyForce(wind);
    particles[i].update();
    particles[i].show();
    if (particles[i].finished()) {
      particles.splice(i, 1);
    }
  }
}

class Particle {

  constructor() {
    this.x = width/2+random(-30,30);
    this.y = height-20;
    this.vx = random(-1, 1);
    this.vy = random(-3, -1);
    this.h = random(340,380)%360;
    this.b = random(50,80);
    this.max = random(width/200,width/50);
    this.d = random(this.max/2,this.max*2);
    this.alpha = map(this.d,0,this.max*2,0,100);
    this.freq = 0;
  }

  finished() {
    return this.alpha < 0;
  }
  applyForce(_wind) {
        this.x += _wind;     
  }

  update() {
    this.freq = map(noise(frameCount /100),0,1,0,3);
    this.x += this.vx+map(noise(this.x/10,this.y/10,frameCount/100),0,1,-this.freq,this.freq);
        if(this.x < width/2){
            this.x += random(-0.05,0.1);
        }
        if(this.x > width/2){
            this.x -= random(-0.05,0.1);         
        }
    this.y += this.vy-noise(this.x/100,frameCount/500);
    this.alpha -= 0.5;       
    this.d = map(this.alpha,0,100,0,this.max);
  }

  show() {
    noStroke();
    fill(this.h,100,this.b,this.alpha);
    ellipse(this.x, this.y, this.d);
  }

}