boardgame-core/docs/game-host.md

3.4 KiB
Raw Blame History

使用 GameHost

GameHost 是游戏运行的核心容器,负责管理游戏状态、命令执行和玩家交互的生命周期。

创建 GameHost

通过 createGameHost 传入一个 GameModule 来创建:

import { createGameHost } from 'boardgame-core';
import * as tictactoe from 'boardgame-core/samples/tic-tac-toe';

const host = createGameHost(tictactoe);

响应式状态

GameHost 暴露的所有属性都是响应式 Signal可以直接用于 UI 渲染或 effect()

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() 并传入初始化命令名来启动游戏:

await host.setup('setup');

这会重置游戏状态、取消当前活动提示、运行指定的 setup 命令,并将状态设为 'running'

处理玩家输入

当命令通过 this.prompt() 等待玩家输入时,使用 onInput() 提交输入:

// 提交玩家操作,返回错误信息或 null
const error = host.onInput('play X 1 2');

if (error) {
    console.log('输入无效:', error);
    // 玩家可以重新输入
} else {
    // 输入已被接受,命令继续执行
}

监听事件

// 监听游戏设置完成
host.on('setup', () => {
    console.log('Game initialized');
});

// 监听游戏销毁
host.on('dispose', () => {
    console.log('Game disposed');
});

// on() 返回取消订阅函数
const unsubscribe = host.on('setup', handler);
unsubscribe(); // 取消监听

重新开始游戏

// 取消当前命令,重置状态,重新运行 setup 命令
await host.setup('setup');

销毁游戏

host.dispose();

销毁后会取消所有活动命令、清理事件监听器,并将状态设为 'disposed'。销毁后无法再次使用。

完整示例

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();

动画同步

如需在状态更新之间播放动画,参考 动画与状态更新同步