init: board game phaser start

This commit is contained in:
2026-04-03 15:18:47 +08:00
commit 588d28ff07
23 changed files with 3552 additions and 0 deletions
@@ -0,0 +1,47 @@
import Phaser from 'phaser';
import { effect } from '@preact/signals-core';
import type { MutableSignal, IGameContext, CommandResult } from 'boardgame-core';
type DisposeFn = () => void;
export interface ReactiveSceneOptions<TState extends Record<string, unknown>> {
state: MutableSignal<TState>;
commands: IGameContext<TState>['commands'];
}
export abstract class ReactiveScene<TState extends Record<string, unknown>> extends Phaser.Scene {
protected state!: MutableSignal<TState>;
protected commands!: IGameContext<TState>['commands'];
private effects: DisposeFn[] = [];
constructor(key: string) {
super(key);
}
protected watch(fn: () => void): DisposeFn {
const e = effect(fn);
this.effects.push(e);
return e;
}
protected async runCommand<T = unknown>(input: string): Promise<CommandResult<T>> {
return this.commands.run<T>(input);
}
create(): void {
this.events.on('shutdown', this.cleanupEffects, this);
this.onStateReady(this.state.value);
this.setupBindings();
}
private cleanupEffects(): void {
for (const e of this.effects) {
e();
}
this.effects = [];
}
protected abstract onStateReady(state: TState): void;
protected abstract setupBindings(): void;
}