UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

126 lines (95 loc) 3.77 kB
import { Tag } from "../../src/engine/ecs/components/Tag.js"; import { EventType } from "../../src/engine/ecs/EventType.js"; import { Camera } from "../../src/engine/graphics/ecs/camera/Camera.js"; import { Light } from "../../src/engine/graphics/ecs/light/Light.js"; import Mesh from "../../src/engine/graphics/ecs/mesh/Mesh.js"; import { ParticleEmitter } from "../../src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js"; import LabelView from "../../src/view/common/LabelView.js"; import EmptyView from "../../src/view/elements/EmptyView.js"; import ImageView from "../../src/view/elements/image/ImageView.js"; /** * * @return {(function(entity:number, ecd:EntityComponentDataset, view:View):void)[]} */ export function makeEntityDecorators() { /** * * @param {number} entity * @param {EntityComponentDataset} ecd * @param {View} view */ function decorate_tags(entity, ecd, view) { const tag = ecd.getComponent(entity, Tag); if (tag === undefined) { return; } const vTags = new EmptyView({ classList: ['tag-container'] }); view.addChild(vTags); tag.traverse(n => { const lTag = new LabelView(n, { classList: ['tag'] }); vTags.addChild(lTag); }); } const component_icons = new Map([ [Mesh, "data/textures/icons/editor/cube-shaded-v1.png"], [ParticleEmitter, "data/textures/icons/editor/particles.png"], [Light, "data/textures/icons/editor/light.png"], [Camera, "data/textures/icons/editor/camera.png"], [Tag, "data/textures/icons/editor/tag-v0.png"], ]); /** * * @param {number} entity * @param {EntityComponentDataset} ecd * @param {View} view */ function decorate_component_icons(entity, ecd, view) { const vIconContainer = new EmptyView({ css: { pointerEvents: "none", display: "flex", flexDirection: "row", justifyContent: "flex-end", filter: "drop-shadow(0 0 2px rgba(0,0,0,0.6))" } }); /** * * @type {Map<any, View>} */ const icons = new Map(); function update() { for (const [Klass, icon_url] of component_icons) { const has_icon = icons.has(Klass); const has_component = ecd.hasComponent(entity, Klass); if (!has_icon && has_component) { const icon = new ImageView(icon_url); icon.size.set(18, 18); vIconContainer.addChild(icon); icons.set(Klass, icon); } else if (has_icon && !has_component) { vIconContainer.removeChild(icons.get(Klass)); icons.delete(Klass); } } } function subscribe() { ecd.addEntityEventListener(entity, EventType.ComponentAdded, update); ecd.addEntityEventListener(entity, EventType.ComponentRemoved, update); } function unsubscribe() { ecd.removeEntityEventListener(entity, EventType.ComponentAdded, update); ecd.removeEntityEventListener(entity, EventType.ComponentRemoved, update); } view.on.linked.add(subscribe); view.on.linked.add(update); view.on.unlinked.add(unsubscribe); view.addChild(vIconContainer); } return [ // decorate_tags, decorate_component_icons ]; }