var Color = use('color') var os = use('os') var graphics = use('graphics') var transform = use('transform') var ex = {} ex.emitters = new Set() ex.garbage = function() { ex.emitters.delete(this) } ex.update = function(dt) { for (var e of ex.emitters) try { e.step(dt) } catch(e) { console.error(e) } } ex.step_hook = function(p) { if (p.time < this.grow_for) { var s = Math.lerp(0, this.scale, p.time / this.grow_for); p.transform.scale = s; } else if (p.time > p.life - this.shrink_for) { var s = Math.lerp(0, this.scale, (p.life - p.time) / this.shrink_for); p.transform.scale = s; } else p.transform.scale = [this.scale, this.scale, this.scale]; } ex.step = function(dt) { // update spawning particles if (this.on && this.pps > 0) { this.spawn_timer += dt; var pp = 1 / this.pps; while (this.spawn_timer > pp) { this.spawn_timer -= pp; this.spawn(); } } // update all particles for (var p of this.particles) { p.time += dt; p.transform.move(p.body.velocity?.scale(dt)); this.step_hook?.(p); if (this.kill_hook?.(p) || p.time >= p.life) { this.die_hook?.(p); this.dead.push(p); this.particles.delete(p); } } } ex.burst = function(count,t) { for (var i = 0; i < count; i++) this.spawn(t) } ex.spawn = function(t) { t ??= this.transform var par = this.dead.shift() if (par) { par.transform.unit() par.transform.pos = t.pos; par.transform.scale = this.scale; this.particles.push(par); par.time = 0; this.spawn_hook?.(par); par.life = this.life; return; } par = { transform: new transform, life: this.life, time: 0, color: this.color, body:{}, } par.transform.scale = this.scale this.particles.push(par) this.spawn_hook(par) } ex.stat = function() { var stat = {}; stat.emitters = emitters.length; var particles = 0; for (var e of emitters) particles += e.particles.length; stat.particles = particles; return stat; } ex.life = 10 ex.scale = 1 ex.grow_for = 0 ex.spawn_timer = 0 ex.pps = 0 ex.color = Color.white ex.draw = function() { /* var diff = graphics.texture(this.diffuse) if (!diff) throw new Error("emitter does not have a proper diffuse texture") var mesh = graphics.make_sprite_mesh(this.particles) if (mesh.num_indices === 0) return render.queue({ type:'geometry', mesh, image:diff, pipeline, first_index:0, num_indices:mesh.num_indices }) */ } return ex --- this.particles = [] this.dead = [] this.transform = this.overling.transform $.emitters.add(this)