UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

134 lines (97 loc) 3.99 kB
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]; } }