npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

zh-chess

v2.1.1

Published

A Chinese chess framework that supports browsers and nodejs(一款运行在浏览器和nodejs环境的中国象棋框架)

Downloads

20

Readme

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)) // 每次运动 自己去调用游戏绘画