boardgame-core/docs/game-host.md

152 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 使用 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.state.value.currentPlayer);
console.log(host.state.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.state.value;
console.log(`${state.currentPlayer}'s turn (turn ${state.turn + 1})`);
if (state.winner) {
console.log('Winner:', state.winner);
}
});
// 启动游戏
await host.setup('setup');
// 游戏循环:等待提示 → 提交输入
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)。