diff --git a/packages/framework/src/scenes/GameHostScene.ts b/packages/framework/src/scenes/GameHostScene.ts index 746d49f..86faa85 100644 --- a/packages/framework/src/scenes/GameHostScene.ts +++ b/packages/framework/src/scenes/GameHostScene.ts @@ -1,5 +1,5 @@ import type { GameHost } from 'boardgame-core'; -import { ReactiveScene, type ReactiveScenePhaserData } from './ReactiveScene'; +import { ReactiveScene } from './ReactiveScene'; export interface GameHostSceneOptions> { gameHost: GameHost; diff --git a/packages/framework/src/scenes/ReactiveScene.ts b/packages/framework/src/scenes/ReactiveScene.ts index ac6ca01..645e969 100644 --- a/packages/framework/src/scenes/ReactiveScene.ts +++ b/packages/framework/src/scenes/ReactiveScene.ts @@ -6,7 +6,7 @@ type CleanupFn = void | (() => void); // 前向声明,避免循环导入 export interface SceneController { - launch(sceneKey: string, data?: Record): Promise; + launch(sceneKey: string): Promise; currentScene: ReadonlySignal; isTransitioning: ReadonlySignal; } diff --git a/packages/framework/src/ui/PhaserBridge.tsx b/packages/framework/src/ui/PhaserBridge.tsx index 079cd93..947c2f5 100644 --- a/packages/framework/src/ui/PhaserBridge.tsx +++ b/packages/framework/src/ui/PhaserBridge.tsx @@ -1,14 +1,14 @@ import Phaser from 'phaser'; -import { computed, signal, useSignal, useSignalEffect } from '@preact/signals'; +import { signal, useSignal, useSignalEffect } from '@preact/signals'; import { createContext, h } from 'preact'; import { useContext } from 'preact/hooks'; import {ReadonlySignal} from "@preact/signals-core"; -import type { ReactiveScene, ReactiveScenePhaserData } from '../scenes'; +import type { ReactiveScene } from '../scenes'; import { FadeScene as FadeSceneClass, FADE_SCENE_KEY } from '../scenes/FadeScene'; export interface SceneController { /** 启动场景(带淡入淡出过渡) */ - launch(sceneKey: string, data?: Record): Promise; + launch(sceneKey: string): Promise; /** 当前活跃场景 key */ currentScene: ReadonlySignal; /** 是否正在过渡 */ @@ -33,12 +33,14 @@ export const defaultPhaserConfig: Phaser.Types.Core.GameConfig = { export interface PhaserGameProps { config?: Partial; + /** 初始启动的场景 key */ + initialScene?: string; children?: any; } export function PhaserGame(props: PhaserGameProps) { const gameSignal = useSignal({ game: undefined!, sceneController: undefined! }); - const registeredScenes = useSignal>(new Map()); + const initialSceneLaunched = useSignal(false); useSignalEffect(() => { const config: Phaser.Types.Core.GameConfig = { @@ -56,7 +58,7 @@ export function PhaserGame(props: PhaserGameProps) { const isTransitioning = signal(false); const sceneController: SceneController = { - async launch(sceneKey: string, data?: Record) { + async launch(sceneKey: string) { if (isTransitioning.value) { console.warn('SceneController: 正在进行场景切换'); return; @@ -74,7 +76,7 @@ export function PhaserGame(props: PhaserGameProps) { } // 启动新场景 - phaserGame.scene.start(sceneKey, data); + phaserGame.scene.start(sceneKey); currentScene.value = sceneKey; // 淡入 @@ -89,11 +91,20 @@ export function PhaserGame(props: PhaserGameProps) { return () => { gameSignal.value = { game: undefined!, sceneController: undefined! }; - registeredScenes.value.clear(); + initialSceneLaunched.value = false; phaserGame.destroy(true); }; }); + // 启动初始场景 + useSignalEffect(() => { + const ctx = gameSignal.value; + if (!initialSceneLaunched.value && props.initialScene && ctx?.sceneController) { + initialSceneLaunched.value = true; + ctx.sceneController.launch(props.initialScene); + } + }); + return (
@@ -132,7 +143,7 @@ export function PhaserScene = {}>(props: P game.scene.add(props.sceneKey, props.scene, false, initData); } sceneSignal.value = props.scene; - + return () => { sceneSignal.value = undefined; // 不在这里移除场景,让 SceneController 管理生命周期 diff --git a/packages/sample-game/src/scenes/GameScene.ts b/packages/sample-game/src/scenes/GameScene.ts index d9e351c..7eb0b4e 100644 --- a/packages/sample-game/src/scenes/GameScene.ts +++ b/packages/sample-game/src/scenes/GameScene.ts @@ -86,8 +86,7 @@ export class GameScene extends GameHostScene { } private async goToMenu(): Promise { - const data = this.initData as unknown as Record; - await this.sceneController.launch('MenuScene', data); + await this.sceneController.launch('MenuScene'); } private setupInput(): void { diff --git a/packages/sample-game/src/ui/App.tsx b/packages/sample-game/src/ui/App.tsx index ff7ff41..5247172 100644 --- a/packages/sample-game/src/ui/App.tsx +++ b/packages/sample-game/src/ui/App.tsx @@ -1,18 +1,13 @@ -import { createGameHost } from 'boardgame-core'; -import { h } from 'preact'; +import { h } from 'preact'; import {PhaserGame, PhaserScene } from 'boardgame-phaser'; import {MenuScene} from "@/scenes/MenuScene"; import {useMemo} from "preact/hooks"; import * as gameModule from '../game/tic-tac-toe'; import {GameScene} from "@/scenes/GameScene"; +import {createGameHost} from "boardgame-core"; export default function App() { - - const gameHost = useMemo(() => { - const gameHost = createGameHost(gameModule); - return { gameHost }; - }, []); - + const gameHost = useMemo(() => createGameHost(gameModule), []); const gameScene = useMemo(() => new GameScene(), []); const menuScene = useMemo(() => new MenuScene(), []); @@ -21,7 +16,7 @@ export default function App() {
- +