fix: api changes fix

This commit is contained in:
hypercross 2026-04-04 23:10:32 +08:00
parent c85fdb604c
commit 61857b8256
3 changed files with 25 additions and 15 deletions

View File

@ -18,11 +18,11 @@ export abstract class GameHostScene<TState extends Record<string, unknown>>
public get gameHost(): GameHost<TState> { public get gameHost(): GameHost<TState> {
return this._gameHost; return this._gameHost;
} }
addInterruption(promise: Promise<void>){ addInterruption(promise: Promise<void>){
this.gameHost?.addInterruption(promise); this.gameHost?.addInterruption(promise);
} }
addTweenInterruption(tween: Phaser.Tweens.Tween){ addTweenInterruption(tween: Phaser.Tweens.Tween){
this.addInterruption(new Promise( this.addInterruption(new Promise(
resolve => tween.once('complete', resolve) resolve => tween.once('complete', resolve)
@ -43,7 +43,7 @@ export abstract class GameHostScene<TState extends Record<string, unknown>>
/** 获取当前状态的只读快照 */ /** 获取当前状态的只读快照 */
public get state(): TState { public get state(): TState {
return this.gameHost.state.value; return this.gameHost.context.value;
} }
public addDisposable(disposable: IDisposable){ public addDisposable(disposable: IDisposable){

View File

@ -1,7 +1,7 @@
import { import {
createGameCommandRegistry, Part, createRegion, createPart, isCellOccupied as isCellOccupiedUtil, createGameCommandRegistry, Part, createRegion, createPart, isCellOccupied as isCellOccupiedUtil,
IGameContext IGameContext, Command
} from '@/index'; } from 'boardgame-core';
const BOARD_SIZE = 3; const BOARD_SIZE = 3;
const MAX_TURNS = BOARD_SIZE * BOARD_SIZE; const MAX_TURNS = BOARD_SIZE * BOARD_SIZE;
@ -19,7 +19,7 @@ const WINNING_LINES: number[][][] = [
export type PlayerType = 'X' | 'O'; export type PlayerType = 'X' | 'O';
export type WinnerType = PlayerType | 'draw' | null; export type WinnerType = PlayerType | 'draw' | null;
type TicTacToePart = Part<{ player: PlayerType }>; export type TicTacToePart = Part<{ player: PlayerType }>;
export function createInitialState() { export function createInitialState() {
return { return {
@ -44,7 +44,7 @@ async function setup(game: TicTacToeGame) {
const turnOutput = await turnCommand(game, currentPlayer, turnNumber); const turnOutput = await turnCommand(game, currentPlayer, turnNumber);
if (!turnOutput.success) throw new Error(turnOutput.error); if (!turnOutput.success) throw new Error(turnOutput.error);
game.produce(state => { game.produce((state: TicTacToeState) => {
state.winner = turnOutput.result.winner; state.winner = turnOutput.result.winner;
if (!state.winner) { if (!state.winner) {
state.currentPlayer = state.currentPlayer === 'X' ? 'O' : 'X'; state.currentPlayer = state.currentPlayer === 'X' ? 'O' : 'X';
@ -61,7 +61,7 @@ registry.register('setup', setup);
async function turn(game: TicTacToeGame, turnPlayer: PlayerType, turnNumber: number) { async function turn(game: TicTacToeGame, turnPlayer: PlayerType, turnNumber: number) {
const {player, row, col} = await game.prompt( const {player, row, col} = await game.prompt(
'play <player> <row:number> <col:number>', 'play <player> <row:number> <col:number>',
(command) => { (command: Command) => {
const [player, row, col] = command.params as [PlayerType, number, number]; const [player, row, col] = command.params as [PlayerType, number, number];
if (player !== turnPlayer) { if (player !== turnPlayer) {
@ -124,9 +124,20 @@ export function placePiece(host: TicTacToeGame, row: number, col: number, player
{ regionId: 'board', position: [row, col], player }, { regionId: 'board', position: [row, col], player },
`piece-${player}-${moveNumber}` `piece-${player}-${moveNumber}`
); );
host.produce(state => { host.produce((state: TicTacToeState) => {
state.parts[piece.id] = piece; state.parts[piece.id] = piece;
board.childIds.push(piece.id); board.childIds.push(piece.id);
board.partMap[`${row},${col}`] = piece.id; board.partMap[`${row},${col}`] = piece.id;
}); });
} }
export const gameModule = {
registry,
createInitialState,
};
export const commands = {
play: (player: PlayerType, row: number, col: number) => {
return `play ${player} ${row} ${col}`;
},
};

View File

@ -2,7 +2,6 @@ import Phaser from 'phaser';
import type {TicTacToeState, TicTacToePart} from '@/game/tic-tac-toe'; import type {TicTacToeState, TicTacToePart} from '@/game/tic-tac-toe';
import { GameHostScene } from 'boardgame-phaser'; import { GameHostScene } from 'boardgame-phaser';
import { spawnEffect, type Spawner } from 'boardgame-phaser'; import { spawnEffect, type Spawner } from 'boardgame-phaser';
import type { ReadonlySignal } from '@preact/signals-core';
import {commands} from "@/game/tic-tac-toe"; import {commands} from "@/game/tic-tac-toe";
const CELL_SIZE = 120; const CELL_SIZE = 120;
@ -26,9 +25,9 @@ export class GameScene extends GameHostScene<TicTacToeState> {
this.gridGraphics = this.add.graphics(); this.gridGraphics = this.add.graphics();
this.drawGrid(); this.drawGrid();
this.disposables.add(spawnEffect(new TicTacToePartSpawner(this, this.gameHost.state))); this.disposables.add(spawnEffect(new TicTacToePartSpawner(this)));
this.watch(() => { this.addEffect(() => {
const winner = this.state.winner; const winner = this.state.winner;
if (winner) { if (winner) {
this.showWinner(winner); this.showWinner(winner);
@ -38,7 +37,7 @@ export class GameScene extends GameHostScene<TicTacToeState> {
} }
}); });
this.watch(() => { this.addEffect(() => {
const currentPlayer = this.state.currentPlayer; const currentPlayer = this.state.currentPlayer;
this.updateTurnText(currentPlayer); this.updateTurnText(currentPlayer);
}); });
@ -163,10 +162,10 @@ export class GameScene extends GameHostScene<TicTacToeState> {
} }
class TicTacToePartSpawner implements Spawner<TicTacToePart, Phaser.GameObjects.Text> { class TicTacToePartSpawner implements Spawner<TicTacToePart, Phaser.GameObjects.Text> {
constructor(public readonly scene: GameScene, public readonly state: ReadonlySignal<TicTacToeState>) {} constructor(public readonly scene: GameScene) {}
*getData() { *getData() {
for (const part of Object.values(this.state.value.parts)) { for (const part of Object.values(this.scene.state.parts)) {
yield part; yield part;
} }
} }