2026-04-04 13:08:28 +08:00
|
|
|
import Phaser from 'phaser';
|
2026-04-04 16:34:17 +08:00
|
|
|
import { effect } from '@preact/signals-core';
|
2026-04-04 13:08:28 +08:00
|
|
|
import type { GameHost } from 'boardgame-core';
|
|
|
|
|
import { DisposableBag, type IDisposable } from '../utils';
|
|
|
|
|
|
|
|
|
|
type CleanupFn = void | (() => void);
|
|
|
|
|
|
|
|
|
|
export interface GameHostSceneOptions<TState extends Record<string, unknown>> {
|
|
|
|
|
gameHost: GameHost<TState>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export abstract class GameHostScene<TState extends Record<string, unknown>>
|
|
|
|
|
extends Phaser.Scene
|
|
|
|
|
implements IDisposable
|
|
|
|
|
{
|
|
|
|
|
protected disposables = new DisposableBag();
|
2026-04-04 16:34:17 +08:00
|
|
|
private _gameHost!: GameHost<TState>;
|
|
|
|
|
public get gameHost(): GameHost<TState> {
|
|
|
|
|
return this._gameHost;
|
|
|
|
|
}
|
2026-04-04 23:10:32 +08:00
|
|
|
|
2026-04-04 15:40:18 +08:00
|
|
|
addInterruption(promise: Promise<void>){
|
|
|
|
|
this.gameHost?.addInterruption(promise);
|
|
|
|
|
}
|
2026-04-04 23:10:32 +08:00
|
|
|
|
2026-04-04 15:43:50 +08:00
|
|
|
addTweenInterruption(tween: Phaser.Tweens.Tween){
|
|
|
|
|
this.addInterruption(new Promise(
|
|
|
|
|
resolve => tween.once('complete', resolve)
|
|
|
|
|
));
|
|
|
|
|
}
|
2026-04-04 13:08:28 +08:00
|
|
|
|
|
|
|
|
init(data: GameHostSceneOptions<TState>): void {
|
2026-04-04 16:34:17 +08:00
|
|
|
this._gameHost = data.gameHost;
|
2026-04-04 13:08:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
create(): void {
|
|
|
|
|
this.events.on('shutdown', this.dispose, this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dispose(): void {
|
|
|
|
|
this.disposables.dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 获取当前状态的只读快照 */
|
2026-04-04 15:40:18 +08:00
|
|
|
public get state(): TState {
|
2026-04-04 23:10:32 +08:00
|
|
|
return this.gameHost.context.value;
|
2026-04-04 13:08:28 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-04 16:34:17 +08:00
|
|
|
public addDisposable(disposable: IDisposable){
|
|
|
|
|
this.disposables.add(disposable);
|
|
|
|
|
}
|
2026-04-04 13:08:28 +08:00
|
|
|
/** 注册响应式监听(场景关闭时自动清理) */
|
2026-04-04 16:34:17 +08:00
|
|
|
public addEffect(fn: () => CleanupFn): void {
|
2026-04-04 13:08:28 +08:00
|
|
|
this.disposables.add(effect(fn));
|
|
|
|
|
}
|
|
|
|
|
}
|