@hiddentao/clockwork-engine
Version:
A TypeScript/PIXI.js game engine for deterministic, replayable games with built-in rendering
106 lines (105 loc) • 4.07 kB
JavaScript
/**
* Web Input Layer
*
* DOM-based input implementation wrapping pointer and keyboard events.
*/
import { EventCallbackManager } from "../utils/EventCallbackManager";
export class WebInputLayer {
constructor(container, audioLayer) {
this.container = container;
this.audioLayer = audioLayer;
this.pointerDownCallbacks = new EventCallbackManager();
this.pointerUpCallbacks = new EventCallbackManager();
this.pointerMoveCallbacks = new EventCallbackManager();
this.clickCallbacks = new EventCallbackManager();
this.keyDownCallbacks = new EventCallbackManager();
this.keyUpCallbacks = new EventCallbackManager();
this.boundPointerDownHandler = this.handlePointerDown.bind(this);
this.boundPointerUpHandler = this.handlePointerUp.bind(this);
this.boundPointerMoveHandler = this.handlePointerMove.bind(this);
this.boundClickHandler = this.handleClick.bind(this);
this.boundKeyDownHandler = this.handleKeyDown.bind(this);
this.boundKeyUpHandler = this.handleKeyUp.bind(this);
container.addEventListener("pointerdown", this.boundPointerDownHandler);
container.addEventListener("pointerup", this.boundPointerUpHandler);
container.addEventListener("pointermove", this.boundPointerMoveHandler);
container.addEventListener("click", this.boundClickHandler);
window.addEventListener("keydown", this.boundKeyDownHandler);
window.addEventListener("keyup", this.boundKeyUpHandler);
}
onPointerDown(callback) {
this.pointerDownCallbacks.register(callback);
}
onPointerUp(callback) {
this.pointerUpCallbacks.register(callback);
}
onPointerMove(callback) {
this.pointerMoveCallbacks.register(callback);
}
onClick(callback) {
this.clickCallbacks.register(callback);
}
onKeyDown(callback) {
this.keyDownCallbacks.register(callback);
}
onKeyUp(callback) {
this.keyUpCallbacks.register(callback);
}
removeAllListeners() {
this.container.removeEventListener("pointerdown", this.boundPointerDownHandler);
this.container.removeEventListener("pointerup", this.boundPointerUpHandler);
this.container.removeEventListener("pointermove", this.boundPointerMoveHandler);
this.container.removeEventListener("click", this.boundClickHandler);
window.removeEventListener("keydown", this.boundKeyDownHandler);
window.removeEventListener("keyup", this.boundKeyUpHandler);
this.pointerDownCallbacks.clear();
this.pointerUpCallbacks.clear();
this.pointerMoveCallbacks.clear();
this.clickCallbacks.clear();
this.keyDownCallbacks.clear();
this.keyUpCallbacks.clear();
}
handlePointerDown(e) {
const event = this.normalizePointerEvent(e);
this.pointerDownCallbacks.trigger(event);
}
handlePointerUp(e) {
const event = this.normalizePointerEvent(e);
this.pointerUpCallbacks.trigger(event);
}
handlePointerMove(e) {
const event = this.normalizePointerEvent(e);
this.pointerMoveCallbacks.trigger(event);
}
handleClick(e) {
this.audioLayer?.tryResumeOnce();
const event = this.normalizePointerEvent(e);
this.clickCallbacks.trigger(event);
}
handleKeyDown(e) {
this.audioLayer?.tryResumeOnce();
const event = {
key: e.key,
code: e.code,
timestamp: Date.now(),
};
this.keyDownCallbacks.trigger(event);
}
handleKeyUp(e) {
const event = {
key: e.key,
code: e.code,
timestamp: Date.now(),
};
this.keyUpCallbacks.trigger(event);
}
normalizePointerEvent(e) {
const rect = this.container.getBoundingClientRect();
return {
x: e.clientX - rect.left,
y: e.clientY - rect.top,
button: e.button,
timestamp: Date.now(),
};
}
}