@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
190 lines (146 loc) • 5.73 kB
JavaScript
import List from '../../../src/core/collection/list/List.js';
import ObservedValue from '../../../src/core/model/ObservedValue.js';
import Clock from "../../../src/engine/Clock.js";
import { decodeMouseEventButtons } from "../../../src/engine/input/devices/mouse/decodeMouseEventButtons.js";
import { PointerDevice } from '../../../src/engine/input/devices/PointerDevice.js';
import GridPaintTool from "../GridPaintTool.js";
import { TerrainHeightPaintTool } from "../paint/TerrainHeightPaintTool.js";
import { TerrainTexturePaintTool } from "../paint/TerrainTexturePaintTool.js";
import SelectionTool from '../SelectionTool.js';
import TopDownCameraControlTool from '../TopDownCameraControlTool.js';
import { TransformTool } from "../TransformTool.js";
class ToolEngine {
/**
*
* @constructor
* @property {List.<Tool>} tools
* @property {ObservedValue.<Tool>} active
*/
constructor() {
this.tools = new List();
this.active = new ObservedValue(null);
this.engine = null;
this.isRunning = false;
this.shutdownCallbacks = [];
this.pointer = null;
}
activate(toolName) {
const self = this;
this.tools.visitFirstMatch(function (tool) {
return tool.name === toolName;
}, function (tool) {
self.active.set(tool);
});
}
initialize() {
this.active.onChanged.add((newTool, oldTool) => {
console.log("active tool changed. Old: ", oldTool, ", New :", newTool);
if (oldTool !== null && typeof oldTool === "object") {
oldTool.finalize();
}
if (newTool !== null && typeof newTool === "object") {
newTool.editor = this.editor;
newTool.engine = this.engine;
newTool.initialize();
}
});
const terrainPaintToolRaise = new TerrainHeightPaintTool();
terrainPaintToolRaise.name = "terrain-height";
const terrainTexturePaintTool0 = new TerrainTexturePaintTool();
terrainTexturePaintTool0.name = `terrain-texture-0`;
terrainTexturePaintTool0.settings.splatIndex = 0;
const terrainTexturePaintTool1 = new TerrainTexturePaintTool();
terrainTexturePaintTool1.name = `terrain-texture-1`;
terrainTexturePaintTool1.settings.splatIndex = 1;
const terrainTexturePaintTool2 = new TerrainTexturePaintTool();
terrainTexturePaintTool2.name = `terrain-texture-2`;
terrainTexturePaintTool2.settings.splatIndex = 2;
const terrainTexturePaintTool3 = new TerrainTexturePaintTool();
terrainTexturePaintTool3.name = `terrain-texture-3`;
terrainTexturePaintTool3.settings.splatIndex = 3;
const tools = this.tools;
tools
.add(new SelectionTool())
.add(new TopDownCameraControlTool())
.add(new GridPaintTool())
.add(new TransformTool())
.add(terrainPaintToolRaise)
.add(terrainTexturePaintTool0)
.add(terrainTexturePaintTool1)
.add(terrainTexturePaintTool2)
.add(terrainTexturePaintTool3)
;
}
/**
*
* @param {Engine} engine
* @param {Editor} editor
*/
startup(engine, editor) {
this.engine = engine;
this.editor = editor;
this.isRunning = true;
const pointer = this.pointer = new PointerDevice(engine.graphics.domElement);
const self = this;
const clock = new Clock();
clock.start();
function update() {
if (!self.isRunning) {
return;
}
requestAnimationFrame(update);
const tool = self.active.get();
const delta = clock.getDelta();
if (tool !== null) {
tool.update(delta);
}
}
//start update loop
update();
//hook up interaction controls
function pointerDown(position, event) {
const tool = self.active.get();
if (tool !== null) {
tool.modifiers.shift = event.shiftKey;
if (typeof event.buttons === "number") {
const decodedButtons = decodeMouseEventButtons(event.buttons);
const isPrimaryPressed = decodedButtons[0];
if (!isPrimaryPressed) {
//when working with mouse, only activate on primary mouse button
return;
}
}
tool.start();
}
}
function pointerUp(position, event) {
const tool = self.active.get();
if (tool !== null) {
tool.stop();
}
}
pointer.on.down.add(pointerDown);
pointer.on.up.add(pointerUp);
pointer.start();
function cleanup() {
pointer.on.down.remove(pointerDown);
pointer.on.up.remove(pointerUp);
pointer.stop();
}
this.shutdownCallbacks.push(cleanup);
}
shutdown() {
this.isRunning = false;
const toolProxy = this.active;
const tool = toolProxy.getValue();
if (tool !== null) {
toolProxy.set(null);
}
//execute cleanup
this.shutdownCallbacks.forEach(function (cb) {
cb();
});
this.shutdownCallbacks = [];
}
}
export default ToolEngine;