@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
126 lines (95 loc) • 3.77 kB
JavaScript
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
];
}