refactor(sts-like-viewer): simplify scene management and config

- Move configuration to `src/config/index.ts`
- Simplify `App.tsx` by passing scene classes directly to `PhaserScene`
- Update `GameUI` initialization to use string ID for container
- Update documentation to mention `initData` for `ReactiveScene`
- Standardize quote usage and formatting in config files
This commit is contained in:
hypercross 2026-04-20 15:24:07 +08:00
parent 2d412eedb5
commit 1d803dd219
4 changed files with 40 additions and 58 deletions

View File

@ -32,8 +32,8 @@ packages/my-game/
### 1. ReactiveScene / GameHostScene
Extend `ReactiveScene`(`packages\framework\src\scenes\ReactiveScene.ts`) to use reactive integration features.
- Access game context for scene navigation
- Use `this.disposables` for auto-cleanup on shutdown.
- Use `initData` for context data passed from the `<PhaserScene/>` preact component.
### 2. Spawner Pattern
Implement `Spawner<TData, TObj>` for data-driven objects.

View File

@ -3,6 +3,8 @@
* All magic numbers should be defined here and imported where needed.
*/
import { PhaserGameProps } from "boardgame-phaser";
// ── Map Layout ──────────────────────────────────────────────────────────────
export const MAP_CONFIG = {
@ -83,9 +85,9 @@ export const UI_CONFIG = {
/** Button border color */
BUTTON_BORDER: 0x7777aa,
/** Button text color */
BUTTON_TEXT_COLOR: '#ffffff',
BUTTON_TEXT_COLOR: "#ffffff",
/** Button font size */
BUTTON_FONT_SIZE: '16px',
BUTTON_FONT_SIZE: "16px",
} as const;
// ── Colors ──────────────────────────────────────────────────────────────────
@ -102,14 +104,14 @@ export const NODE_COLORS = {
} as const;
export const NODE_LABELS = {
start: '起点',
end: '终点',
minion: '战斗',
elite: '精英',
event: '事件',
camp: '营地',
shop: '商店',
curio: '奇遇',
start: "起点",
end: "终点",
minion: "战斗",
elite: "精英",
event: "事件",
camp: "营地",
shop: "商店",
curio: "奇遇",
} as const;
export const ITEM_COLORS = [
@ -118,5 +120,20 @@ export const ITEM_COLORS = [
// ── Positive/Negative Effects (for buff icons) ──────────────────────────────
export const POSITIVE_EFFECTS = new Set(['block', 'strength', 'dexterity', 'regen']);
export const NEGATIVE_EFFECTS = new Set(['weak', 'vulnerable', 'frail', 'poison']);
export const POSITIVE_EFFECTS = new Set([
"block",
"strength",
"dexterity",
"regen",
]);
export const NEGATIVE_EFFECTS = new Set([
"weak",
"vulnerable",
"frail",
"poison",
]);
export const GAME_CONFIG: Phaser.Types.Core.GameConfig = {
width: 1920,
height: 1080,
};

View File

@ -1,10 +1,9 @@
import { h } from 'preact';
import { GameUI } from 'boardgame-phaser';
import './style.css';
import { GameUI } from "boardgame-phaser";
import "./style.css";
import App from "@/ui/App";
const ui = new GameUI({
container: document.getElementById('ui-root')!,
container: "ui-root",
root: <App />,
});

View File

@ -1,53 +1,19 @@
import { h } from "preact";
import { PhaserGame, PhaserScene } from "boardgame-phaser";
import { useMemo } from "preact/hooks";
import { IndexScene } from "@/scenes/IndexScene";
import { MapViewerScene } from "@/scenes/MapViewerScene";
import { GridViewerScene } from "@/scenes/GridViewerScene";
import { ShapeViewerScene } from "@/scenes/ShapeViewerScene";
import { GameFlowScene } from "@/scenes/GameFlowScene";
import { PlaceholderEncounterScene } from "@/scenes/PlaceholderEncounterScene";
import { createGameState } from "@/state/gameState";
// 全局游戏状态单例
const gameState = createGameState();
import { GAME_CONFIG } from "@/config";
export default function App() {
const indexScene = useMemo(() => new IndexScene(), []);
const mapViewerScene = useMemo(() => new MapViewerScene(), []);
const gridViewerScene = useMemo(() => new GridViewerScene(), []);
const shapeViewerScene = useMemo(() => new ShapeViewerScene(), []);
const gameFlowScene = useMemo(() => new GameFlowScene(gameState), []);
const placeholderEncounterScene = useMemo(
() => new PlaceholderEncounterScene(gameState),
[],
);
return (
<div className="flex flex-col h-screen">
<div className="flex-1 flex relative justify-center items-center">
<PhaserGame
initialScene="IndexScene"
config={{ width: 1920, height: 1080 }}
>
<PhaserScene sceneKey="IndexScene" scene={indexScene as any} />
<PhaserScene
sceneKey="MapViewerScene"
scene={mapViewerScene as any}
/>
<PhaserScene
sceneKey="GridViewerScene"
scene={gridViewerScene as any}
/>
<PhaserScene
sceneKey="ShapeViewerScene"
scene={shapeViewerScene as any}
/>
<PhaserScene sceneKey="GameFlowScene" scene={gameFlowScene as any} />
<PhaserScene
sceneKey="PlaceholderEncounterScene"
scene={placeholderEncounterScene as any}
/>
<PhaserGame initialScene="IndexScene" config={GAME_CONFIG}>
<PhaserScene scene={IndexScene} />
<PhaserScene scene={MapViewerScene} />
<PhaserScene scene={GridViewerScene} />
<PhaserScene scene={ShapeViewerScene} />
</PhaserGame>
</div>
</div>