xxxxxxxxxx
130
const grav = 0.1;
let f = [];
let start;
function setup() {
createCanvas(600, 600);
colorMode(HSB);
noStroke();
f.push(new Firework(createVector(width/2, height), createVector(0, -8), 50, random(255)));
}
function draw() {
background(0, 0, 0, 0.2);
if(mouseIsPressed) {
stroke(0, 255, 255);
line(mouseX, mouseY, start.x, start.y);
noStroke();
}
f = f.filter(fw => {
fw.draw();
return fw.update();
});
}
function mousePressed() {
start = createVector(mouseX, mouseY);
}
function mouseReleased() {
let dy = start.y - mouseY;
let dx = start.x - mouseX;
let d = dist(mouseX, mouseY, start.x, start.y);
let a = atan2(dy, dx);
let force = map(d, 0, width, 1, 10);
f.push(new Firework(
start,
createVector(cos(a) * force, sin(a) * force),
random(50, 150),
random(128)
));
}
class Firework {
constructor(pos, vel, num, col) {
this.pos = pos;
this.vel = vel;
this.num = num;
this.col = col;
this.burst = false;
this.particles = [];
}
update() {
if(!this.burst) {
if(this.vel.y >= 1) {
this.explode();
}
this.vel.y += grav;
this.pos.x += this.vel.x;
this.pos.y += this.vel.y;
} else {
for(let i = this.particles.length - 1; i >= 0; i --) {
let alive = this.particles[i].update();
if(!alive) {
this.particles.splice(i, 1);
}
}
return this.particles.length > 0;
}
return true;
}
explode() {
this.burst = true;
for(let i = 0; i < this.num; i ++) {
let a = (i/this.num) * TAU;
let f = random(1, 5);
this.particles.push(new Particle(
createVector(this.pos.x, this.pos.y),
createVector(cos(a) * f + this.vel.x, sin(a) * f + this.vel.y),
random(30, 100)
));
}
}
draw() {
fill(this.col, 255, 255);
if(this.burst) {
for(let i = 0; i < this.particles.length; i ++) {
this.particles[i].draw();
}
} else {
ellipse(this.pos.x, this.pos.y, 5, 5);
}
}
}
class Particle {
constructor(pos, vel, lifetime) {
this.pos = pos;
this.vel = vel;
this.maxLife = lifetime;
this.lifetime = lifetime;
}
update() {
this.lifetime --;
if(this.lifetime <= 0) {
return false;
}
this.vel.y += grav;
this.pos.x += this.vel.x;
this.pos.y += this.vel.y;
return true;
}
draw() {
let s = (this.lifetime/this.maxLife) * 5;
ellipse(this.pos.x, this.pos.y, s, s);
}
}