一款JavaScript语言编写的**象棋游戏框架,支持nodejs,浏览器,vue,react等前端框架。(支持typescript)更多象棋知识
- 项目新增依赖(需要借助canvas来显示游戏图片)
D:your project>npm i zh-chess canvas -D # or cnpm i zh-chess canvas -D
- 直接导入使用
const {
createCanvas
} = require('canvas')
const CTX_WIDTH = 375,
CTX_HEIGHT = 375
const canvas = createCanvas(CTX_WIDTH, CTX_HEIGHT)
const ctx = canvas.getContext('2d')
const ZhChess = require("zh-chess").default
const fs = require('fs')
const out = fs.createWriteStream('./test.jpg') // 创建文件流
const game = new ZhChess({
ctx,
gameWidth: CTX_WIDTH,
gameHeight: CTX_HEIGHT
})
game.gameStart("RED") // 开始游戏
game.moveStr("炮2平5", "RED") // 移动棋子
const stream = canvas.createJPEGStream()
stream.pipe(out) // 写入文件
out.on('finish', () => console.log('The JPEG file was created.'))
- 下载源码
git clone https://github.com/kongyijilafumi/zh-chess
# or 国内码云
git clone https://gitee.com/kong_yiji_and_lavmi/zh-chess
- 在html的
head
部分使用script
标签引入./lib/zh-chess.browser.min.js
文件
<head>
<script script="./lib/zh-chess.browser.min.js"></script>
</head>
- 引入之后的下方,新建
script
标签,直接调用api即可。
<head>
<script script="./lib/zh-chess.browser.min.js"></script>
</head>
<body>
<canvas id="canvas" height="375" width="375" style="width:375px;height:375px;"></canvas>
</body>
<script>
const app = document.getElementById("canvas")
const ctx = app.getContext("2d")
const zhchess = new ZhChess.default({
ctx,
gameWidth: 375,
gameHeight: 375
})
// 绑定点击事件
app.addEventListener("click", zhchess.listenClickAsync, false)
</script>
- 安装依赖
your project>npm i zh-chess -D #or cnpm i zh-chess
- 在
vue2.x
项目中使用
<template>
<canvas ref="canvas" height="375" width="375" style="width: 375px; height: 375px;" />
</template>
<script>
import ZhChess from "zh-chess";
export default {
data() {
return {
game: null
}
},
mounted() {
const canvas = this.$refs.canvas;
const ctx = canvas.getContext("2d");
this.game = new ZhChess({
ctx,
gameHeight: 375,
gameWidth: 375,
moveSpeed: 12,
});
this.game.gameStart("RED"); // 以红方开始游戏
canvas.addEventListener("click", this.game.listenClickAsync, false);
},
}
</script>
- 在
vue3.x
项目中使用
<template>
<canvas ref="canvas" height="375" width="375" style="width: 375px; height: 375px;" />
</template>
<script lang="ts" setup>
import ZhChess, {
GameOverCallback,
MoveCallback,
MoveFailCallback,
} from "zh-chess";
import {
onMounted,
reactive,
ref,
getCurrentInstance
} from "vue";
const page = getCurrentInstance();
const CANVAS_WIDTH = 375;
const CANVAS_HEIGHT = 375;
let game = reactive({}
as ZhChess);
const onOver: GameOverCallback = (winnerSide) => {
console.log(`${winnerSide}胜`);
};
// 挂载
onMounted(() => {
const canvas = page?.refs.canvas as HTMLCanvasElement;
game = new ZhChess({
ctx: canvas.getContext("2d") as CanvasRenderingContext2D,
gameHeight: CANVAS_WIDTH,
gameWidth: CANVAS_HEIGHT,
});
game.gameStart("RED");
canvas.addEventListener("click", game.listenClickAsync, false);
game.on("over", onOver);
});
</script>
- 在
react
项目中使用
import ZhChess from "zh-chess"
import { useEffect, useRef, useState } from "react";
export default function App() {
const [gameInstance, setGame] = useState<ZhChess | null>(null)
const canvas = useRef<HTMLCanvasElement>(null)
useEffect(() => {
if (canvas.current) {
const CTX_WIDTH = 375, CTX_HEIGHT = 375,ctx = canvas.current.getContext('2d') as CanvasRenderingContext2D;
const game = new ZhChess({
ctx,
gameHeight: CTX_HEIGHT,
gameWidth: CTX_WIDTH
})
game.gameStart("RED")
canvas.current.addEventListener("click", game.listenClickAsync, false)
setGame(game)
}
}, [canvas])
return <div className="app">
<canvas ref={canvas} width="375" height="375" style={{width:375,height:375}} />
</div>
}
- ctx:画布
- gameWidth:
number
游戏窗口宽度默认:800
- gameHeight:
number
游戏窗口高度默认:800
- gamePadding:
number
棋盘的内边距默认:20
- scaleRatio:
number
画布缩放比例默认:1
(用于移动端,解决画布模糊问题) - moveSpeed:
number
移动速度默认8
(越大越慢,>=1)
运行速度 大于或等于 1 的数 越大越慢
选择玩家方并且初始化游戏,side只能是 RED
| BLACK
.
const game = new ZhChess({
ctx,
gameHeight: 375,
gameWidth: 375
})
game.gameStart("RED")
用于dom的点击事件,此方法棋子运动无动画,且为同步执行函数。
const app = document.getElementById("canvas")
const ctx = app.getContext("2d")
const game = new ZhChess.default({
ctx,
gameWidth: 375,
gameHeight: 375
})
// 绑定点击事件
app.addEventListener("click", game.listenClick, false)
用于dom的点击事件,此方法执行棋子运动有动画(根据 moveSpeed
大小来决定运动时长),且为异步执行函数。
const app = document.getElementById("canvas")
const ctx = app.getContext("2d")
const game = new ZhChess.default({
ctx,
gameWidth: 375,
gameHeight: 375
})
// 绑定点击事件
app.addEventListener("click", game.listenClickAsync, false)
更换玩家视角
game.changePlaySide("RED") // 红方视角 红在下 黑在上
game.changePlaySide("BLACK") // 黑方视角 黑在下 红在上
棋子运动前检查游戏状态是否可以运动
游戏是否结束
根据 红方在下黑方在上的
视角(也是棋子游戏里的固定坐标 不分红黑方视角
) 来指定坐标点移动到指定的坐标点,无移动动画,返回移动结果,同步方法。
0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8
0 車 馬 象 仕 將 仕 象 馬 車 0 馬 象 仕 將 仕 象 馬 車
1 1
2 砲 砲 2 車 砲 砲
3 卒 卒 卒 卒 卒 3 卒 卒 卒 卒 卒
4 --> 4
5 --> 5
6 兵 兵 兵 兵 兵 --> 6 兵 兵 兵 兵 兵
7 炮 炮 7 炮 炮
8 8
9 车 马 相 士 帅 士 相 马 车 9 车 马 相 士 帅 士 相 马 车
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
以
红方在下黑方在上的
视角移动棋子最左上为x,y轴的起始位置,往下y变大,往右x变大。如图所示,坐标点为(0, 0)移动到了(0, 2)位置,表示黑
方車
向前进两个格子
代码如下所示。
const piecePoint = {
x: 0,
y: 0
},
movePoint = {
x: 0,
y: 2
}
game.move(piecePoint, movePoint, "BLACK") // 返回 { flag:true } 或者 { flag:false, message:"xxx" }
跟move方法作用一样,不过是异步的,有动画效果。
通过文字的形式根据 红黑方视角
来移动象棋。无移动动画,同步方法,返回移动结果。
10
9
8
7
6
5
4 兵 兵 兵 兵 兵
3 炮 炮
2
1 车 马 相 士 帅 士 相 马 车
1 2 3 4 5 6 7 8 9
已红方或黑方自己视角,靠近对方底线为进,靠近己方底线为退,横着走为平。例如:车1进1是指自己左边的车往前走一步。
game.move("车1进1", "RED") // 红方 车1进1 返回 { flag:true } 或者 { flag:false, message:"xxx" }
跟moveStr方法作用一样,不过是异步的,有动画效果。
游戏监听事件
-
e为
move
时,fn函数的参数有(peice: ChessOfPeice, cp: CheckPoint, enemyhasTrouble: boolean)
-
e为
moveFail
时,fn函数的参数有(peice: ChessOfPeice, p: Point, currentSideDanger: boolean, msg: string)
-
e为
log
时,fn函数的参数有(str: any)
-
e为
over
时,fn函数的参数有(winnerSide: PieceSide)
移除游戏的监听函数
设置当前存活棋子列表