update: various improvements
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import Phaser from 'phaser';
|
||||
import type { TicTacToeState, TicTacToePart, PlayerType } from '@/game/tic-tac-toe';
|
||||
import { isCellOccupied } from 'boardgame-core';
|
||||
import { ReactiveScene, bindRegion, createInputMapper, createPromptHandler } from 'boardgame-phaser';
|
||||
import type { PromptEvent } from 'boardgame-core';
|
||||
|
||||
@@ -48,7 +47,7 @@ export class GameScene extends ReactiveScene<TicTacToeState> {
|
||||
bindRegion<TicTacToeState, { player: PlayerType }>(
|
||||
this.state,
|
||||
(state) => state.parts,
|
||||
this.state.value.board,
|
||||
(state) => state.board,
|
||||
{
|
||||
cellSize: { x: CELL_SIZE, y: CELL_SIZE },
|
||||
offset: BOARD_OFFSET,
|
||||
@@ -59,6 +58,15 @@ export class GameScene extends ReactiveScene<TicTacToeState> {
|
||||
color: part.player === 'X' ? '#3b82f6' : '#ef4444',
|
||||
}).setOrigin(0.5);
|
||||
|
||||
// 添加落子动画
|
||||
text.setScale(0);
|
||||
this.tweens.add({
|
||||
targets: text,
|
||||
scale: 1,
|
||||
duration: 200,
|
||||
ease: 'Back.easeOut',
|
||||
});
|
||||
|
||||
return text;
|
||||
},
|
||||
update: (part, obj) => {
|
||||
@@ -69,8 +77,32 @@ export class GameScene extends ReactiveScene<TicTacToeState> {
|
||||
);
|
||||
}
|
||||
|
||||
private isCellOccupied(row: number, col: number): boolean {
|
||||
const state = this.state.value;
|
||||
return !!state.board.partMap[`${row},${col}`];
|
||||
}
|
||||
|
||||
private setupInput(): void {
|
||||
this.inputMapper = createInputMapper(this, this.commands);
|
||||
const scene = this;
|
||||
const activePromptRef = {
|
||||
get current() { return scene.activePrompt; }
|
||||
};
|
||||
|
||||
this.inputMapper = createInputMapper(
|
||||
this,
|
||||
this.commands,
|
||||
activePromptRef,
|
||||
(cmd: string) => {
|
||||
const activePrompt = this.activePrompt;
|
||||
if (!activePrompt) return 'No active prompt';
|
||||
const error = activePrompt.tryCommit(cmd);
|
||||
if (error === null) {
|
||||
this.activePrompt = null;
|
||||
this.promptHandler.start();
|
||||
}
|
||||
return error;
|
||||
}
|
||||
);
|
||||
|
||||
this.inputMapper.mapGridClick(
|
||||
{ x: CELL_SIZE, y: CELL_SIZE },
|
||||
@@ -80,7 +112,7 @@ export class GameScene extends ReactiveScene<TicTacToeState> {
|
||||
if (this.state.value.winner) return null;
|
||||
|
||||
const currentPlayer = this.state.value.currentPlayer;
|
||||
if (isCellOccupied(this.state.value.parts, 'board', [row, col])) return null;
|
||||
if (this.isCellOccupied(row, col)) return null;
|
||||
|
||||
return `play ${currentPlayer} ${row} ${col}`;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user