avocado-old/packages/graphics/traits/emitter.trait.js

124 lines
2.7 KiB
JavaScript
Raw Normal View History

2019-04-28 23:45:03 -05:00
import {compose, Property} from '@avocado/core';
2019-04-20 16:03:11 -05:00
import {Trait} from '@avocado/entity';
2019-04-25 02:28:54 -05:00
import {Ticker} from '@avocado/timing';
2019-04-20 16:03:11 -05:00
const decorate = compose(
2019-04-28 23:45:03 -05:00
);
2019-04-20 16:03:11 -05:00
export class Emitter extends decorate(Trait) {
constructor(entity, params, state) {
super(entity, params, state);
2019-04-20 16:03:11 -05:00
this.emitters = {};
if (AVOCADO_CLIENT) {
this.ticker = new Ticker(1 / 10);
this.ticker.on('tick', this.onTick, this);
}
2019-04-20 16:03:11 -05:00
}
2019-05-05 04:26:35 -05:00
static type() {
return 'emitter';
}
2019-04-25 19:19:38 -05:00
static addEmitter(emitter) {
if (!this._emitters) {
this._emitters = [];
}
this._emitters.push(emitter);
}
static particleCount() {
let particleCount = 0;
if (!this._emitters) {
return particleCount;
}
for (let i = 0; i < this._emitters.length; i++) {
const emitter = this._emitters[i];
particleCount += emitter.particleCount;
}
return particleCount;
}
static removeEmitter(emitter) {
const index = this._emitters.indexOf(emitter);
if (-1 === index) {
return;
}
this._emitters.splice(index, 1);
}
onTick(elapsed) {
this.updateFrequency();
for (const key in this.emitters) {
const emitter = this.emitters[key];
emitter.tick(elapsed);
}
}
2019-04-25 19:19:38 -05:00
updateFrequency() {
const particleCount = this.constructor.particleCount();
const updatesPerSecond = Math.max(15, (60 - (particleCount / 10)));
this.ticker.frequency = 1 / updatesPerSecond;
}
2019-04-20 16:03:11 -05:00
hooks() {
2019-05-02 21:07:43 -05:00
const hooks = {};
if (AVOCADO_CLIENT) {
hooks.afterDestructionTickers = () => {
2019-04-20 16:03:11 -05:00
return (elapsed) => {
for (const key in this.emitters) {
const emitter = this.emitters[key];
2019-04-25 02:28:54 -05:00
this.ticker.tick(elapsed);
2019-04-20 16:03:11 -05:00
if (!emitter.hasParticles()) {
this.ticker.off('tick', this.onTick);
2019-04-25 19:19:38 -05:00
emitter.destroy();
2019-04-30 17:11:41 -05:00
this.constructor.removeEmitter(emitter);
2019-04-20 16:03:11 -05:00
delete this.emitters[key];
}
}
return 0 === Object.keys(this.emitters).length;
};
2019-05-02 21:07:43 -05:00
};
2019-04-20 16:03:11 -05:00
}
2019-05-02 21:07:43 -05:00
return hooks;
2019-04-20 16:03:11 -05:00
}
methods() {
return {
addEmitter: (key, emitter) => {
2019-05-02 21:07:43 -05:00
if (AVOCADO_SERVER) {
return;
}
2019-04-20 16:03:11 -05:00
this.emitters[key] = emitter;
2019-04-25 19:19:38 -05:00
this.constructor.addEmitter(emitter);
2019-04-20 16:03:11 -05:00
},
addEmitterRenderer: (key, renderer) => {
2019-05-02 21:07:43 -05:00
if (AVOCADO_SERVER) {
return;
}
2019-04-20 16:03:11 -05:00
if (!this.emitters[key]) {
return;
}
this.emitters[key].addRenderer(renderer);
},
emitParticle: (key, ...args) => {
if (!this.emitters[key]) {
return;
}
this.emitters[key].emit(...args);
},
}
}
2019-05-02 22:17:41 -05:00
tick(elapsed) {
if (AVOCADO_CLIENT) {
this.ticker.tick(elapsed);
}
2019-04-20 16:03:11 -05:00
}
}