From 02d2f45da297ad814050a9157e922e42acd1d384 Mon Sep 17 00:00:00 2001 From: hyper Date: Sun, 12 Apr 2026 19:17:22 +0800 Subject: [PATCH] refactor: fix onitama sizing --- packages/onitama-game/src/scenes/MenuScene.ts | 6 +-- .../onitama-game/src/scenes/OnitamaScene.ts | 16 ++++---- .../onitama-game/src/spawners/CardSpawner.ts | 37 ++++++++++++------- .../onitama-game/src/spawners/PawnSpawner.ts | 2 +- packages/onitama-game/src/ui/App.tsx | 2 +- 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/packages/onitama-game/src/scenes/MenuScene.ts b/packages/onitama-game/src/scenes/MenuScene.ts index ce95674..b6021b2 100644 --- a/packages/onitama-game/src/scenes/MenuScene.ts +++ b/packages/onitama-game/src/scenes/MenuScene.ts @@ -17,12 +17,12 @@ const MENU_CONFIG = { }, button: { width: 200, - height: 60, + height: 80, }, positions: { - titleY: -100, + titleY: -120, buttonY: 40, - subtitleY: 140, + subtitleY: 160, }, } as const; diff --git a/packages/onitama-game/src/scenes/OnitamaScene.ts b/packages/onitama-game/src/scenes/OnitamaScene.ts index 51df91d..e7db5c1 100644 --- a/packages/onitama-game/src/scenes/OnitamaScene.ts +++ b/packages/onitama-game/src/scenes/OnitamaScene.ts @@ -60,11 +60,11 @@ export class OnitamaScene extends GameHostScene { // Info text this.infoText = this.add.text( - 20, + 40, BOARD_OFFSET.y, '', { - fontSize: '15px', + fontSize: '16px', fontFamily: 'Arial', color: '#4b5563', } @@ -94,7 +94,7 @@ export class OnitamaScene extends GameHostScene { // Red cards label - 棋盘下方 const redLabel = this.add.text( boardLeft + (BOARD_SIZE * CELL_SIZE) / 2, - boardBottom + 10, + boardBottom + 40, "RED", { fontSize: '16px', @@ -107,7 +107,7 @@ export class OnitamaScene extends GameHostScene { // Black cards label - 棋盘上方 const blackLabel = this.add.text( boardLeft + (BOARD_SIZE * CELL_SIZE) / 2, - boardTop - 10, + boardTop - 40, "BLACK", { fontSize: '16px', @@ -150,8 +150,8 @@ export class OnitamaScene extends GameHostScene { g.strokePath(); this.add.text( - 20, - 20, + 40, + 40, 'Onitama', { fontSize: '28px', @@ -231,8 +231,8 @@ export class OnitamaScene extends GameHostScene { /** 创建菜单按钮 */ private createMenuButton(): void { - const buttonX = this.game.scale.width - 80; - const buttonY = 30; + const buttonX = 680; + const buttonY = 40; this.menuButtonBg = this.add.rectangle(buttonX, buttonY, 120, 40, 0x6b7280) .setInteractive({ useHandCursor: true }); diff --git a/packages/onitama-game/src/spawners/CardSpawner.ts b/packages/onitama-game/src/spawners/CardSpawner.ts index d7f4cff..099aa57 100644 --- a/packages/onitama-game/src/spawners/CardSpawner.ts +++ b/packages/onitama-game/src/spawners/CardSpawner.ts @@ -5,9 +5,10 @@ import type { OnitamaScene } from '@/scenes/OnitamaScene'; import { BOARD_OFFSET, CELL_SIZE } from './PawnSpawner'; import { effect } from "@preact/signals-core"; -export const CARD_WIDTH = 100; -export const CARD_HEIGHT = 140; +export const CARD_WIDTH = 80; +export const CARD_HEIGHT = 120; const BOARD_SIZE = 5; +const CARD_SPACING = 100; // 确保每张卡牌至少 80x80 区域 export interface CardSpawnData { cardId: string; @@ -176,7 +177,7 @@ export class CardContainer extends Phaser.GameObjects.Container { .setStrokeStyle(2, 0x6b7280); this.add(bg); - const title = (this.scene as OnitamaScene).add.text(0, -CARD_HEIGHT / 2 + 15, card.id, { + const title = (this.scene as OnitamaScene).add.text(0, -CARD_HEIGHT / 2 + 16, card.id, { fontSize: '12px', fontFamily: 'Arial', color: '#1f2937', @@ -184,11 +185,11 @@ export class CardContainer extends Phaser.GameObjects.Container { this.add(title); const grid = (this.scene as OnitamaScene).add.graphics(); - const cellSize = 16; + const cellSize = 14; const gridWidth = 5 * cellSize; const gridHeight = 5 * cellSize; const gridStartX = -gridWidth / 2; - const gridStartY = -gridHeight / 2 + 30; + const gridStartY = -gridHeight / 2 + 20; for (let row = 0; row < 5; row++) { for (let col = 0; col < 5; col++) { @@ -209,7 +210,7 @@ export class CardContainer extends Phaser.GameObjects.Container { } this.add(grid); - const playerText = (this.scene as OnitamaScene).add.text(0, CARD_HEIGHT / 2 - 15, card.startingPlayer, { + const playerText = (this.scene as OnitamaScene).add.text(0, CARD_HEIGHT / 2 - 16, card.startingPlayer, { fontSize: '10px', fontFamily: 'Arial', color: '#6b7280', @@ -255,20 +256,20 @@ export class CardSpawner implements Spawner { if (data.position === 'red') { // 红方卡牌在棋盘下方,水平排列 return { - x: boardLeft + BOARD_SIZE * CELL_SIZE / 2 - (data.index - 0.5) * (CARD_WIDTH + 15), - y: boardBottom + CARD_HEIGHT - 30, + x: boardCenterX - (data.index - 0.5) * CARD_SPACING, + y: boardBottom + CARD_HEIGHT / 2 + 40, }; } else if (data.position === 'black') { // 黑方卡牌在棋盘上方,水平排列 return { - x: boardLeft + BOARD_SIZE * CELL_SIZE / 2 - (data.index - 0.5) * (CARD_WIDTH + 15), - y: boardTop - CARD_HEIGHT + 30, + x: boardCenterX - (data.index - 0.5) * CARD_SPACING, + y: boardTop - CARD_HEIGHT / 2 - 40, }; } else { // 备用卡牌在棋盘左侧,垂直居中 const boardCenterY = boardTop + (BOARD_SIZE * CELL_SIZE) / 2; return { - x: boardLeft - CARD_WIDTH, + x: boardLeft - CARD_WIDTH / 2 - 40, y: boardCenterY, }; } @@ -308,7 +309,7 @@ export class CardSpawner implements Spawner { targets: obj, x: pos.x, y: pos.y, - duration: 350, + duration: 600, ease: 'Back.easeOut', }); @@ -329,8 +330,16 @@ export class CardSpawner implements Spawner { return emptyContainer; } - // 计算旋转角度 - 初始不旋转,后续由 onUpdate 处理 - const container = new CardContainer(this.scene, data.cardId, card, 0); + // 计算初始旋转角度 + const isBlackTurn = this.scene.state.currentPlayer === 'black'; + let initialRotation = 0; + if (data.position === 'black') { + initialRotation = -180; + } else if (data.position === 'spare' && isBlackTurn) { + initialRotation = -180; + } + + const container = new CardContainer(this.scene, data.cardId, card, initialRotation); const pos = this.getCardPosition(data); container.x = pos.x; container.y = pos.y; diff --git a/packages/onitama-game/src/spawners/PawnSpawner.ts b/packages/onitama-game/src/spawners/PawnSpawner.ts index 5566356..edc197c 100644 --- a/packages/onitama-game/src/spawners/PawnSpawner.ts +++ b/packages/onitama-game/src/spawners/PawnSpawner.ts @@ -6,7 +6,7 @@ import type { OnitamaUIState } from '@/state'; import { effect } from "@preact/signals-core"; export const CELL_SIZE = 80; -export const BOARD_OFFSET = { x: 240, y: 200 }; +export const BOARD_OFFSET = { x: 240, y: 240 }; export const BOARD_SIZE = 5; export function boardToScreen(boardX: number, boardY: number): { x: number; y: number } { diff --git a/packages/onitama-game/src/ui/App.tsx b/packages/onitama-game/src/ui/App.tsx index 928e166..4a7dddc 100644 --- a/packages/onitama-game/src/ui/App.tsx +++ b/packages/onitama-game/src/ui/App.tsx @@ -15,7 +15,7 @@ export default function App() { return (
- +