太长不看:直接点击这里查看代码
BoardGame.io 是一个专门为回合制游戏打造的游戏引擎。无需一行网络或存储相关的代码,只需要编写简单函数描述游戏动作如何影响游戏状态,即可自动帮你生成一个支持多人在线的完整游戏。它支持回合制游戏的方方面面,比如状态管理、多人在线、AI、游戏进程或回合管理、游戏大厅等诸多功能。今天我们就用它结合 React 制作一个五子棋游戏。
准备
首先,我们准备一个 React 项目,并添加 boadgame.io 依赖。
npx create-react-app gomoku
cd gomoku
npm install boardgame.io
定义游戏
接下来,我们要定义游戏。定义游戏相当于告诉 boardgame.io 游戏是怎么玩的。由于引擎会管理好当前玩家、游戏是否结束等这些状态,对于五子棋游戏来说,只剩下局面信息需要定义了。通过创建一个满足特定接口的对象,即可定义一个游戏。这些接口当中,setup 函数是起点,它负责创建游戏状态 G。而 moves 则定义了此游戏中有多少种可以执行的动作。
动作实际是一个函数,它接收当前状态 G 作为参数,并对它进行修改,使它成为新的状态。动作函数还接收另外一个参数 ctx, 它包含当前玩家、当前回合等这些信息,由 boardgame.io 管理,无法修改。除 G 和 ctx 外,其它参数你可自由定义,它们将被视为执行该动作的额外参数。
五子棋游戏中,我们只有一个动作,就是落子。且把它命名为 putStone,它需要一个 ID 参数告诉它该在哪里下子。
创建 src/Game.js 文件,并添加以下内容:
export const Gomoku = {
setup: () => ({
stones: Array(15*15).fill(0) }),
moves: {
putStone: (G, ctx, id) => {
G.stones[id] = [1,-1][ctx.currentPlayer];
},
},
};
定义客户端
客户端相当于一个可以玩游戏,只不过只能通过 API 玩。将 src/App.js 内容替换为以下内容:
import {
Client } from 'boardgame.io/react';
import {
Gomoku } from './Game';
const App = Client({
game: Gomoku});
export default App;
若此时运行 npm start ,会看到一个 UI,这是 boardgame.io 渲染的 Debug 面板。当前状态下,使用这个 UI 下虽然也可以进行游戏,但玩起来相当费劲,就不介绍了。
Debug 面板在生产环境构建时 (
NODE_ENV='production')会被自动去除,也可以在Client的配置中添加debug: false关闭。
改善游戏逻辑
着法验证
目前为止,若玩家对已经落子的位置调用 putStone , 则那个位置的棋子会被覆盖。这挺扯的,需要防止。
要让 boardgame.io 就能知道此着法是无效的,需返回一个从 boardgame.io 中引入的特别常量:
import {
INVALID_MOVE } from 'boardgame.io/core';
现在,我们在 putStone 中验证着法并返回 INVALID_MOVE:
putStone: (G, ctx, id) => {
if (G.stones[id] !== 0) {
return INVALID_MOVE;
}
G.stones[id] = [1,-1][ctx.currentPlayer];
}
回合管理
不同的游戏,玩家在一回合可以进行的动作数量可能不同,结束回合的条件也不同。有的游戏一回合可以进行多个动作,有的一回合一个动作。五子棋就是一回合一个动作的游戏。在 Debug 面板中,我们可以点击 endTurn 手动结束回合。其实,客户端代码也可以执行完动作后自动结束回合。
在 boardgame.io 中有多种方法管理回合,使用 moveLimit 就是其中之一。下面我们就使用这种方法让引擎自动帮我们结束当前回合:
export const Gomoku = {
setup: () => {
/* ... */ },
turn: {
moveLimit: 1,
},
moves: {
/* ... */ },
};
胜利条件
我们的五子棋游戏定义得差不多了,只差最后一环:胜利局面判断。
首先,我们先加几个函数:
/**
* 检查一条线上某一方是否成 5
* @param {number[]} stones
* @param {number} clr
* @param {number} start
* @param {number} end
* @param {number} stride
*/
function checkWinnerByLine(stones, clr, start, end, stride) {
let cnt = 0;
for (; cnt < 5 && start !== end; start += stride) {
if (stones[start] === clr) cnt++;
else cnt = 0;
}
return cnt >= 5;
}
/**
* 检查某位玩家是否获胜
* @param {number[]} stones
* @param {number} clr
*/
function isVictory(stones, clr) {
const boardSize = 15;
let x = 0,
y = 0;
let start = 0,
end = 0,
stride = 1;
// horizontal
stride = <

本文介绍了使用BoardGame.io结合React制作五子棋游戏的方法。先准备项目并添加依赖,接着定义游戏、客户端,改善游戏逻辑,包括着法验证、回合管理和胜利条件判断。之后制作棋盘,添加AI功能,最后用wgo.js美化棋盘,还可进一步完善游戏。
&spm=1001.2101.3001.5002&articleId=117433757&d=1&t=3&u=b62b03080c534908ac40e9365cc8b096)
560

被折叠的 条评论
为什么被折叠?



