1 Star 4 Fork 3

孔乙己拉夫米 / zh-chess

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

ZhChess(中国象棋)

GitHub star GitHub fork Gitee star Gitee fork

MIT开源协议

一款JavaScript语言编写的中国象棋游戏框架,支持nodejs,浏览器,vue,react等前端框架。(支持typescript)更多象棋知识

案例网站

安装使用

nodejs

  1. 项目新增依赖(需要借助canvas来显示游戏图片)
D:your project>npm i zh-chess canvas -D # or cnpm i zh-chess canvas -D
  1. 直接导入使用
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, // ctx 属性可传 可不传 只要 游戏不需要更新画面 光靠 游戏逻辑来运行完全可以足够
    gameWidth: CTX_WIDTH,
    gameHeight: CTX_HEIGHT
})
game.gameStart("RED") // 开始游戏
game.moveStr("炮2平5", "RED") // 移动棋子
game.draw(ctx) // 更新画布 需要传入画布
const stream = canvas.createJPEGStream()
stream.pipe(out) // 写入文件
out.on('finish', () => console.log('The JPEG file was created.'))

浏览器环境

  1. 下载源码
git clone https://github.com/kongyijilafumi/zh-chess
# or 国内码云
git clone https://gitee.com/kong_yiji_and_lavmi/zh-chess
  1. 在html的 head 部分使用 script 标签引入 ./lib/zh-chess.browser.min.js 文件
<head>
    <script script="./lib/zh-chess.browser.min.js"></script>
</head>
  1. 引入之后的下方,新建 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>

react, vue等前端构建项目使用

  • 安装依赖
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,
                duration: 200, // 默认200 ms单位 值棋子运动时长
            });
            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>
} 

接口

GitHub文档地址 | Gitee文档地址

ZhChess 游戏类

constructor(obj: GameInfo);

GameInfo Properties

  • blackPeiceBackground?: string 黑棋子背景色 默认:#fdec9e
  • checkerboardBackground?: string 棋盘背景色 默认:#faebd7
  • ctx?: CanvasRenderingContext2D 画布

如果不需要游戏显示出来,可以不需要 画布

  • drawMovePoint?: boolean 选中是否绘画可移动的点 默认: true
  • duration?: number 棋子运动速度时长 毫秒单位 默认:200
  • gameHeight?: number 游戏窗口高度大小 默认:800
  • gamePadding?: number 游戏内边距大小距离棋盘 默认:20
  • gameWidth?: number 游戏窗口宽度大小 默认:800
  • movePointColor?: string 绘画可移动点的颜色 默认:#25dd2a
  • redPeiceBackground?: string 红棋子背景色 默认:#feeca0
  • scaleRatio?: number 画布缩放大小 默认:1 (用于移动端,解决画布模糊问题)

Properties

duration: number

Accessors

棋子运动速度时长 毫秒单位

get currentGameSide(): null | PieceSide

获取游戏方

get currentLivePieceList(): PieceList

获取当前存活的棋子列表

get currentRadius(): number

获取当前象棋绘制半径

get winnerSide(): null | PieceSide

获取赢棋方

gameStart(side: PieceSide): void

选择玩家方并且初始化游戏,side只能是 RED | BLACK .

  const game = new ZhChess({
      gameHeight: 375,
      gameWidth: 375
  })
  game.gameStart("RED")

Methods

changeCurrentPlaySide(side: PieceSide): void

更改当前走棋方

changePlaySide(side: PieceSide): void

更换玩家视角

checkDraw(): void

检查是否有画布 有会根据当前棋子位置状态去更新画布 否则不更新 报出错误

checkGameState(): MoveResult

棋子运动前检查游戏状态是否可以运动

draw(ctx: CanvasRenderingContext2D): void

根据当前棋子状态绘画 棋盘状态 游戏数据 画出布局

gameOver(): boolean

游戏是否结束

gameStart(side: PieceSide): void

初始化选择玩家方 初始化棋盘

getCurrentPenCode(side: PieceSide): string

获取当前棋盘的 PEN 格式位置代码

listenClick(e: MouseEvent): void

用于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)
listenClickAsync(e: MouseEvent): void

用于dom的点击事件,此方法执行棋子运动有动画(根据 duration 来决定运动时长),且为异步执行函数。

    const app = document.getElementById("canvas")
    const ctx = app.getContext("2d")
    const game = new ZhChess.default({
        ctx,
        gameWidth: 375,
        gameHeight: 375,
        duration: 500 // 棋子运动时长 500ms
    })
    // 绑定点击事件
    app.addEventListener("click", game.listenClickAsync, false)
moveStr(str: string, side: PieceSide): UpdateResult

通过文字的形式根据 红黑方视角 来移动象棋。无移动动画,同步方法,返回移动结果。

10    
9     
8     
7   
6  
5 
4 兵    兵    兵    兵    兵
3    炮                炮
2                    
1 车 马 相 士 帅  士 相 马 车
  1  2  3  4  5  6  7  8  9 

已红方或黑方自己视角,靠近对方底线为进,靠近己方底线为退,横着走为平。例如:车1进1是指自己左边的车往前走一步。

game.moveStr("车1进1", "RED") // 红方 车1进1 返回 { flag:true } 或者 { flag:false, message:"xxx" } 
moveStrAsync(str: string, side: PieceSide, refreshCtx: boolean): Promise < UpdateResult >

跟moveStr方法作用一样,不过是异步的,有动画效果。 refreshCtx 表示 是否每次移动都更新画布。

on(e: GameEventName, fn: GameEventCallback):void

游戏监听事件

  • 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)

  • e为error时,fn函数的参数有(error: any)

removeEvent(e: GameEventName, fn: GameEventCallback):void

移除游戏的监听函数

setLivePieceList(pl: PieceList): void

设置当前存活棋子列表

setPenCodeList(penCode: string): void

根据pen代码格式来设置当前棋盘

建议参考 文章 博客 https://www.xqbase.com/protocol/cchess_fen.htm

update(pos: Point, mov: null | Point, side: PieceSide, post: boolean): UpdateResult

游戏根据坐标点 移动点来进行更新游戏运行数据。 post :是否由程序自己更新游戏状态。

返回的结果: 如果 post 为 false, 请检查返回的结果 move 是否为 true ,为true表示有返回回调函数cb,只有调用 cb() 游戏状态才会更新。如果 post 为 true,程序会自己更新游戏状态 只需要判断 是否更新成功即可!

updateAsync(pos: Point, mov: null | Point, side: PieceSide, refreshCtx: boolean, moveCallback?: UpdateMoveCallback): Promise < UpdateResult >

游戏根据坐标点 移动点来进行更新游戏运行数据。这是一个返回一个promise结果,也表示 这个方法是异步的。

const ctx = document.getElementById("canvas").getContext("2d")
const game = new ZhChess({})
game.gameStart("RED")
game.updateAsync(pos, mov, side, true, (posPeice, newPoint) => console.log(posPeice, newPoint)) // 每次运动都去绘画一次
game.updateAsync(pos, mov, side, false, (posPeice, newPoint) => game.draw(ctx)) // 每次运动 自己去调用游戏绘画
MIT License Copyright (c) 2022 Zhang Zhengzeng Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

A Chinese chess framework that supports browsers and nodejs(一个支持nodejs跟浏览器环境的中国象棋框架) 游玩网址:https://chess.z3web.cn/ 展开 收起
TypeScript 等 3 种语言
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
TypeScript
1
https://gitee.com/kong_yiji_and_lavmi/zh-chess.git
git@gitee.com:kong_yiji_and_lavmi/zh-chess.git
kong_yiji_and_lavmi
zh-chess
zh-chess
v2.0

搜索帮助