refactor: particley goodness

This commit is contained in:
cha0s 2019-11-05 23:32:51 -06:00
parent 55590c5073
commit 5cfc18a2aa
2 changed files with 94 additions and 8 deletions

View File

@ -15,8 +15,9 @@ export class Emitted extends decorate(Trait) {
end: 1,
},
force: [0, 0],
listed: true,
mass: 1,
position: [0, 0],
position: null,
rotation: {
start: 0,
add: 0,
@ -41,7 +42,12 @@ export class Emitted extends decorate(Trait) {
this.alphaEnd = new Range(this.params.alpha.end);
this.force = new Vector.Range(this.params.force);
this.mass = this.params.mass;
this.position = new Vector.Range(this.params.position);
if (null !== this.params.position) {
this.position = new Vector.Range(this.params.position);
}
else {
this.position = null;
}
this.rotationStart = new Range(this.params.rotation.start);
this.rotationAdd = new Range(this.params.rotation.add);
this.scaleStart = new Range(this.params.scale.start);
@ -58,7 +64,7 @@ export class Emitted extends decorate(Trait) {
return {
particle: () => {
const position = this.position.value();
const position = null === this.position ? null : this.position.value();
const velocity = this.velocity.value();
const force = this.force.value();
return {
@ -67,6 +73,7 @@ export class Emitted extends decorate(Trait) {
end: this.alphaEnd.value(),
},
force,
listed: this.params.listed,
mass: this.mass,
position,
rotation: {

View File

@ -1,6 +1,7 @@
import {compose} from '@avocado/core';
import {compose, merge} from '@avocado/core';
import {Entity, StateProperty, Trait} from '@avocado/entity';
import {Vector} from '@avocado/math';
import {Ticker} from '@avocado/timing';
import {Proton} from '../proton';
@ -11,13 +12,21 @@ const decorate = compose(
export class Emitter extends decorate(Trait) {
static defaultParams() {
return {
particles: {},
};
}
static type() {
return 'emitter';
}
constructor(entity, params, state) {
super(entity, params, state);
this.emissions = [];
this.emitter = new Proton.Emitter();
this.particles = {};
this.proton = new Proton();
this.proton.addEmitter(this.emitter);
this.onParticleDead = this.onParticleDead.bind(this);
@ -27,6 +36,21 @@ export class Emitter extends decorate(Trait) {
this.emitter.addEventListener('PARTICLE_UPDATE', this.onParticleUpdate);
}
gatherParticles() {
const particles = {};
const hookParticles = this.entity.invokeHookFlat('particles');
for (let i = 0; i < hookParticles.length; i++) {
const traitParticles = hookParticles[i];
for (const key in traitParticles) {
particles[key] = traitParticles[key];
}
}
for (const key in this.params.particles) {
particles[key] = this.params.particles[key];
}
this.particles = particles;
}
onParticleDead(particle) {
if (particle.isTransientParticle) {
particle.body.destroy();
@ -54,16 +78,31 @@ export class Emitter extends decorate(Trait) {
return hooks;
}
listeners() {
return {
traitAdded: () => {
this.gatherParticles();
},
};
}
methods() {
return {
emitParticle: (entity) => {
emitParticleEntity: (entity) => {
const particle = entity.particle();
const position = particle.position ?
particle.position
:
this.entity.position
;
const initializers = [
new Proton.Body(entity),
new Proton.Position(new Proton.PointZone(
particle.position[0],
particle.position[1]
position[0],
position[1]
)),
new Proton.Mass(particle.mass),
new Proton.Life(particle.ttl),
@ -98,22 +137,62 @@ export class Emitter extends decorate(Trait) {
entity.on('destroy', () => {
this.emitter.removeParticle(protonParticle);
});
if (particle.listed) {
this.entity.list.addEntity(entity);
}
// Prime.
this.onParticleUpdate(protonParticle);
},
emitParticleJson: (json) => {
return Entity.loadOrInstance(json).then((particle) => {
this.entity.emitParticle(particle);
this.entity.emitParticleEntity(particle);
return particle;
});
},
emitParticle: (key, order = {}) => {
const particleJson = this.particles[key]
if (!particleJson) {
return;
}
const mergedJson = merge({}, particleJson, order);
let {
count = 1,
rate = 0,
} = order;
if (0 === rate) {
for (let i = 0; i < count; ++i) {
this.entity.emitParticleJson(mergedJson);
}
}
else {
const ticker = new Ticker(rate);
this.entity.emitParticleJson(mergedJson);
count -= 1;
if (count > 0) {
ticker.on('tick', () => {
this.emitParticleJson(mergedJson);
if (0 === --count) {
const index = this.emissions.indexOf(ticker);
if (-1 !== index) {
this.emissions.splice(index, 1);
}
}
});
this.emissions.push(ticker);
}
}
},
};
}
tick(elapsed) {
this.emitter.update(elapsed);
for (let i = 0; i < this.emissions.length; i++) {
this.emissions[i].tick(elapsed);
}
}
}