51 lines
1.3 KiB
JavaScript
51 lines
1.3 KiB
JavaScript
import * as Phaser from 'phaser';
|
|
|
|
// Common lifecycle and helpers for any game. Concrete games extend
|
|
// TabletopGame or CasinoGame, which extend this.
|
|
//
|
|
// Subclasses should implement:
|
|
// - createBoard() set up persistent visuals
|
|
// - onState(state) apply an authoritative state update from the server
|
|
// - onInput(action) optional, for client-side input handling
|
|
export default class BaseGame extends Phaser.Scene {
|
|
constructor(key) {
|
|
super(key);
|
|
this.gameDef = null;
|
|
this.room = null;
|
|
this.socket = null;
|
|
this.localUser = null;
|
|
}
|
|
|
|
init(data = {}) {
|
|
this.gameDef = data.game;
|
|
this.room = data.room ?? null;
|
|
this.socket = data.socket ?? null;
|
|
this.localUser = data.user ?? null;
|
|
}
|
|
|
|
create() {
|
|
this.createBoard?.();
|
|
this.bindNetwork();
|
|
}
|
|
|
|
bindNetwork() {
|
|
if (!this.socket) return;
|
|
this.socket.on(`game:${this.gameDef.slug}:state`, this.handleState);
|
|
this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => {
|
|
this.socket.off(`game:${this.gameDef.slug}:state`, this.handleState);
|
|
});
|
|
}
|
|
|
|
handleState = (state) => {
|
|
this.onState?.(state);
|
|
};
|
|
|
|
sendAction(action) {
|
|
if (!this.socket || !this.room) return;
|
|
this.socket.emit(`game:${this.gameDef.slug}:action`, {
|
|
roomId: this.room.id,
|
|
action,
|
|
});
|
|
}
|
|
}
|