45 lines
1.2 KiB
JavaScript
45 lines
1.2 KiB
JavaScript
// 粒子系统
|
|
import { rand, randInt } from './util.js';
|
|
|
|
export class Particles {
|
|
constructor() { this.list = []; }
|
|
clear() { this.list.length = 0; }
|
|
|
|
spawn(x, y, n, opt = {}) {
|
|
const {
|
|
colors = ['#fff', '#ff5c7a', '#ffc63a'],
|
|
speed = 3, life = 40, size = 3, grav = 0.12, spread = Math.PI * 2, dir = 0,
|
|
} = opt;
|
|
for (let i = 0; i < n; i++) {
|
|
const a = dir + (Math.random() - 0.5) * spread;
|
|
const s = rand(speed * 0.35, speed);
|
|
this.list.push({
|
|
x, y, vx: Math.cos(a) * s, vy: Math.sin(a) * s,
|
|
life: life * rand(0.6, 1.25), max: life,
|
|
c: colors[randInt(0, colors.length - 1)],
|
|
s: size * rand(0.6, 1.3), g: grav,
|
|
});
|
|
}
|
|
}
|
|
|
|
burst(x, y, opt = {}) { this.spawn(x, y, opt.n || 18, opt); }
|
|
|
|
update() {
|
|
for (let i = this.list.length - 1; i >= 0; i--) {
|
|
const p = this.list[i];
|
|
p.x += p.vx; p.y += p.vy; p.vy += p.g;
|
|
p.vx *= 0.985;
|
|
if (--p.life <= 0) this.list.splice(i, 1);
|
|
}
|
|
}
|
|
|
|
draw(ctx) {
|
|
for (const p of this.list) {
|
|
ctx.globalAlpha = Math.min(1, p.life / (p.max * 0.5));
|
|
ctx.fillStyle = p.c;
|
|
ctx.fillRect(p.x | 0, p.y | 0, p.s | 0, p.s | 0);
|
|
}
|
|
ctx.globalAlpha = 1;
|
|
}
|
|
}
|