@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
134 lines (97 loc) • 3.99 kB
JavaScript
import { float_to_uint8 } from "../../../../core/binary/float_to_uint8.js";
import { SerializationMetadata } from "../../../ecs/components/SerializationMetadata.js";
import Entity from "../../../ecs/Entity.js";
import { AbstractContextSystem } from "../../../ecs/system/AbstractContextSystem.js";
import { SystemEntityContext } from "../../../ecs/system/SystemEntityContext.js";
import { Transform } from "../../../ecs/transform/Transform.js";
import {
PARTICLE_ATTRIBUTE_COLOR,
PARTICLE_ATTRIBUTE_POSITION
} from "../../particles/particular/engine/emitter/PARTICLE_ATTRIBUTES.js";
import { ParticleEmitter } from "../../particles/particular/engine/emitter/ParticleEmitter.js";
import { ParticleEmitterFlag } from "../../particles/particular/engine/emitter/ParticleEmitterFlag.js";
import { ParticleLayer } from "../../particles/particular/engine/emitter/ParticleLayer.js";
import { Sprite } from "./Sprite.js";
class Context extends SystemEntityContext {
constructor() {
super();
this.__emitter = new ParticleEmitter();
this.__layer = new ParticleLayer();
this.__layer.emissionRate = 0;
this.__layer.emissionImmediate = 1;
this.__layer.steps.reset();
this.__layer.particleLife.set(999999999, 999999999);
this.__emitter.addLayer(this.__layer);
this.__emitter_entity = new Entity()
.add(this.__emitter)
.add(new Transform())
.add(SerializationMetadata.Transient);
}
__copy_transform() {
/**
*
* @type {Transform}
*/
const transform = this.components[1];
this.__emitter_entity.getComponent(Transform).copy(transform);
const emitter = this.__emitter;
emitter.particles?.writeAttributeVector3(0, PARTICLE_ATTRIBUTE_POSITION, transform.position.x, transform.position.y, transform.position.z);
emitter.setFlag(ParticleEmitterFlag.ParticleBoundsNeedUpdate);
}
link() {
if (this.__is_linked) {
return;
}
super.link();
/**
*
* @type {Transform}
*/
const transform = this.components[1];
transform.position.onChanged.add(this.__copy_transform, this);
transform.scale.onChanged.add(this.__copy_transform, this);
/**
*
* @type {Sprite}
*/
const sprite = this.components[0];
this.__layer.imageURL = sprite.url;
this.__layer.particleSize.set(sprite.size, sprite.size);
const emitter = this.__emitter;
if (!emitter.getFlag(ParticleEmitterFlag.Built)) {
//particle pool needs to be set up first
emitter.build();
}
if (!emitter.getFlag(ParticleEmitterFlag.Initialized)) {
//particles are not initialized, do that
emitter.initialize();
}
emitter.particles?.writeAttributeVector4(
0, PARTICLE_ATTRIBUTE_COLOR,
float_to_uint8(sprite.color.r), float_to_uint8(sprite.color.g), float_to_uint8(sprite.color.b), float_to_uint8(sprite.opacity.getValue())
);
this.__copy_transform();
emitter.computeBoundingBox();
this.__emitter_entity.build(this.getDataset());
}
unlink() {
if (!this.__is_linked) {
return;
}
/**
*
* @type {Transform}
*/
const transform = this.components[1];
transform.position.onChanged.remove(this.__copy_transform, this);
transform.scale.onChanged.remove(this.__copy_transform, this);
super.unlink();
this.__emitter_entity.destroy();
}
}
export class SpriteSystemPE extends AbstractContextSystem {
constructor() {
super(Context);
this.dependencies = [Sprite, Transform];
}
}