# 使用 GameHost `GameHost` 是游戏运行的核心容器,负责管理游戏状态、命令执行和玩家交互的生命周期。 ## 创建 GameHost 通过 `createGameHost` 传入一个 GameModule 来创建: ```ts import { createGameHost } from 'boardgame-core'; import * as tictactoe from 'boardgame-core/samples/tic-tac-toe'; const host = createGameHost(tictactoe); ``` ## 响应式状态 GameHost 暴露的所有属性都是响应式 Signal,可以直接用于 UI 渲染或 `effect()`: ```ts import { effect } from '@preact/signals-core'; // 游戏状态 effect(() => { console.log(host.context.value.currentPlayer); console.log(host.context.value.winner); }); // 生命周期状态: 'created' | 'running' | 'disposed' effect(() => { console.log('Status:', host.status.value); }); // 当前等待的玩家输入 schema effect(() => { const schema = host.activePromptSchema.value; if (schema) { console.log('Waiting for:', schema.name, schema.params); } }); // 当前等待的玩家 effect(() => { console.log('Current player prompt:', host.activePromptPlayer.value); }); ``` ## 启动游戏 调用 `setup()` 并传入初始化命令名来启动游戏: ```ts await host.setup('setup'); ``` 这会重置游戏状态、取消当前活动提示、在后台启动指定的 setup 命令(不等待完成),并将状态设为 `'running'`。 ## 处理玩家输入 当命令通过 `this.prompt()` 等待玩家输入时,使用 `onInput()` 提交输入: ```ts // 提交玩家操作,返回错误信息或 null const error = host.onInput('play X 1 2'); if (error) { console.log('输入无效:', error); // 玩家可以重新输入 } else { // 输入已被接受,命令继续执行 } ``` ## 监听事件 ```ts // 监听游戏设置完成 host.on('setup', () => { console.log('Game initialized'); }); // 监听游戏销毁 host.on('dispose', () => { console.log('Game disposed'); }); // on() 返回取消订阅函数 const unsubscribe = host.on('setup', handler); unsubscribe(); // 取消监听 ``` ## 重新开始游戏 ```ts // 取消当前命令,重置状态,重新运行 setup 命令 await host.setup('setup'); ``` ## 销毁游戏 ```ts host.dispose(); ``` 销毁后会取消所有活动命令、清理事件监听器,并将状态设为 `'disposed'`。销毁后无法再次使用。 ## 完整示例 ```ts import { effect } from '@preact/signals-core'; import { createGameHost } from 'boardgame-core'; import * as tictactoe from 'boardgame-core/samples/tic-tac-toe'; const host = createGameHost(tictactoe); // 监听状态变化 effect(() => { const state = host.context.value; console.log(`${state.currentPlayer}'s turn (turn ${state.turn + 1})`); if (state.winner) { console.log('Winner:', state.winner); } }); // 启动游戏 await host.setup('setup'); // 游戏循环:等待提示 → 提交输入 // 注意:setup() 会立即返回,但 prompt 可能需要一些时间才能激活 // 实际应用中应该等待 activePromptSchema 变为非 null while (host.status.value === 'running' && host.activePromptSchema.value) { const schema = host.activePromptSchema.value!; console.log('Waiting for input:', schema.name); // 这里可以从 UI/网络等获取输入 const input = await getPlayerInput(); const error = host.onInput(input); if (error) { console.log('Invalid:', error); } } // 游戏结束后可以重新开始 // await host.setup('setup'); // 或彻底销毁 // host.dispose(); ``` ## 动画同步 如需在状态更新之间播放动画,参考 [动画与状态更新同步](./animation-sync.md)。 `GameHost` 提供了两个方法: | 方法 | 说明 | |---|---| | `addInterruption(promise: Promise)` | 注册动画中断,下一个 `produceAsync` 会等待它 | | `clearInterruptions()` | 清除所有未完成的中断 | ```ts // UI 层:检测到状态变化后播放动画并注册中断 host.addInterruption(playAnimation('place', data)); ```