@hiddentao/clockwork-engine
Version:
A TypeScript/PIXI.js game engine for deterministic, replayable games with built-in rendering
129 lines (128 loc) • 3.85 kB
JavaScript
import { GameEventType } from "./types";
export class GameEventManager {
constructor(source, engine) {
this.currentTick = 0;
this.source = source;
this.engine = engine;
}
/**
* Set the game recorder for this event manager
*/
setRecorder(recorder) {
this.recorder = recorder;
}
/**
* Process events for the current tick
*/
update(_deltaTicks, totalTicks) {
this.currentTick = totalTicks;
// Get all events that are ready for this tick
const events = this.source.getNextEvents(totalTicks);
// Process each event
for (const event of events) {
this.processEvent(event);
// Record the event using the GameRecorder
if (this.recorder) {
this.recorder.recordEvent(event);
}
}
}
/**
* Set a new event source
* @param source The new event source to use
*/
setSource(source) {
this.source = source;
}
/**
* Get the current event source
*/
getSource() {
return this.source;
}
/**
* Reset the event manager
*/
reset() {
this.source.reset();
}
/**
* Process a single game event
*/
processEvent(event) {
try {
switch (event.type) {
case GameEventType.USER_INPUT:
this.processUserInput(event);
break;
case GameEventType.OBJECT_UPDATE:
this.processObjectUpdate(event);
break;
default:
console.warn(`Unknown event type: ${event.type}`);
}
}
catch (error) {
console.error(`Error processing event:`, event, error);
}
}
/**
* Process a user input event
* This is where you would typically dispatch input events to game systems
*/
processUserInput(event) {
// This is a placeholder implementation
// In a real game, you would route input events to the appropriate handlers
// For example: keyboard handlers, mouse handlers, etc.
if (this.onUserInput) {
this.onUserInput(event);
}
}
/**
* Process an object update event
* Finds the target object and calls the specified method with parameters
*/
processObjectUpdate(event) {
const group = this.engine.getGameObjectGroup(event.objectType);
if (!group) {
console.warn(`No group found for object type: ${event.objectType}`);
return;
}
const obj = group.getById(event.objectId);
if (!obj) {
console.warn(`Object not found: ${event.objectId} of type ${event.objectType}`);
return;
}
// Get object position for logging if available
let _position;
if (typeof obj.getPosition === "function") {
const pos = obj.getPosition();
if (pos && typeof pos.x === "number" && typeof pos.y === "number") {
_position = { x: pos.x, y: pos.y };
}
}
const method = obj[event.method];
if (typeof method !== "function") {
console.warn(`Method not found: ${event.method} on object ${event.objectId}`);
return;
}
// Call the method with the provided parameters
;
method.apply(obj, event.params);
}
/**
* Check if there are more events to process
*/
hasMoreEvents() {
return this.source.hasMoreEvents();
}
/**
* Get information about the current event source
*/
getSourceInfo() {
return {
type: this.source.constructor.name,
hasMore: this.source.hasMoreEvents(),
};
}
}