【国际象棋】棋盘游戏-微信小程序开发流程详解

article/2025/9/20 16:13:03

与中国象棋类似的,还有国际象棋,知道有人爱玩,于是凭着好奇心,网上研究了一下,跟中国象棋有相似之处,玩法是有些许不一样,不知道象棋最早出于谁之手呢,抽空做一做,最终完成,玩一玩看着还不错吧,这里给讲一讲它的实现过程。

可能在国内的有些同学没有玩过国际版的象棋,在此简要说明以下规则,以便了解:

  • 后棋:👸皇后,不可越棋;
  • 王棋:🤴国王,限走一格,特殊走法,首次使用可与未使用过的车易位一次(向车方向走两格),若被吃掉就判断为败;
  • 象棋:🐘丞相,斜着走,不可越棋;
  • 马棋:🏇骑士,斜着走一格,再前进一格;
  • 车棋:🛞马车,不可斜着走,不可越棋;
  • 兵棋:♟️卒兵,只能前进一格,首次使用可前进两格,斜着吃,可吃过路兵(左右两边的格子),当前进到对方底线时需要升变换为除王和兵之外的其它棋子;

准备开始做了,打开微信开发者工具,新建一个项目时,如下图
在这里插入图片描述

例如,项目名称为chess_game,依次选择

  • 小程序
  • 不使用云服务
  • 使用JavaScript - 基础模板

这时,开发工具会自动创建生成一些文件,不用管它,

新建一个游戏页面,文件在pages/game/game.wxml,页面的布局大致如下

<view class="page"><view class="top-content"><view class="game-panel"><image class="bg" src="{{bgImg}}" /><image class="bg" src="{{chessesImg}}" /><canvas class="fore" id="canv" type="2d" bindtouchstart="onTouchStart"></canvas></view><view class="padding"><text>🔈 {{showFlagStatus}}</text></view></view><scroll-view scroll-y="true" class="scroll-view"><view class="scroll-view-content"><!-- other layout --></view></scroll-view>
</view>

上面布局中,使用两个图片组件作为静动态背景,还有一个画布用于绘制

先看一下,要做出来的页面是这样的,看如下运行显示效果
在这里插入图片描述

再去修改一下主页(第一个页面),文件在pages/index/index.js

在加载事件里添加一段代码,可实现自动跳转到游戏页面

wx.navigateTo({url: '/pages/game/game',
})

同时打开新建的游戏页面逻辑代码,文件在pages/game/game.js

看好了,接下来开始写游戏逻辑代码,

获取画布组件

首先从页面初次渲染完成时开始写,获取到画布canvas组件,并绑定触摸开始事件,看如下代码

Page({/*** 页面的初始数据*/data: {bgImg:'',//棋盘背景图chessesImg:'',//棋子布局图innertHtml:'',//游戏说明内容showFlagStatus:'请选择任意一方棋子为先手'},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {wx.createSelectorQuery().select('#canv').fields({size:true, node:true}, res=>{//此处省略...获取并设置画布实例this.canvasData = {canvas:res.node,context:res.node.getContext('2d')};//初始化棋盘this.initChessBg();}).exec()},/*** 触摸开始事件*/onTouchStart(e){const touch = e.touches[0];//判断是否游戏结束 正在移动棋子if(this.isGameEnd || this.animatiing) return;const { grids, nSize, myFlag } = this.chessImgData;//根据坐标点查找指定格子数据let grid = grids.find(g=>g.left<=touch.x && g.left+nSize>touch.x && g.top<=touch.y && g.top+nSize>touch.y);//此处省略了实现下棋的规则逻辑,这个要复杂一些,稍后会讲//判断是否自己来下棋if (myFlag!=null && myFlag!=grid.uid) return;//将选择的棋子 用矩形框画出来this.drawSelectGrid(grid);},

生成棋盘

画布组件获取到后,可以在上面绘制棋盘了,

在初始化棋盘方法initChessBg()里实现,生成棋盘图片数据,显示在页面上,代码如下

const { canvas, context:ctx } = this.canvasData;
//先画一个灰色背景
ctx.fillStyle = '#bebebe';
ctx.rect(0,0,canvas.width,canvas.height);
ctx.fill();
//在画一格白色的格子,每隔一格绘制
ctx.fillStyle = '#ffffff';
const cols = Cols;//常量值 8列
let size = Math.floor(canvas.width/cols);
const grids = [];
//绘制所有格子 棋盘
for(let r=0; r<cols; r++){for(let c=0; c<cols; c++){let grid = {//...格子数据};//此处省略了...ctx.rect(grid.left,grid.top,size,size);ctx.fill();grids.push(grid);}
}
//将画出来的生成图片数据
let base64 = canvas.toDataURL();
//该清空了
ctx.clearRect(0,0,canvas.width,canvas.height);
//定义格子的配置数据
let chessImgData = {grids,//...chesses: [],//所有棋子存放在这里myFlag: null,
};
//此处省略了...所有棋子数据
this.chessImgData = chessImgData;
//将棋子图片全部绘制出来
let foreImg = canvas.createImage();
foreImg.onload=()=>{chessImgData.foreImg = foreImg;//绘制所有棋子this.drawAllChess();
};
foreImg.onerror=err=>{console.error(err)
};
//从静态资源中加载棋子分布的图片
foreImg.src='/static/chess.png';
this.setData({bgImg:base64
});

把图片弄到背景图片中,这样就可以了,看看显示的棋盘,运行效果如下
在这里插入图片描述

生成所有棋子

棋盘绘制好了,还差点什么呢,还要绘制所有棋子,

使用方法drawAllChess()可画出所有的棋子,在棋盘之上布局,

然后,生成图片,弄到画布的下层,叠加起来,类似图层,看如下代码

const { canvas, context:ctx } = this.canvasData;
const { chessImgData } = this;
//避免污染,先清理一下画布
ctx.clearRect(0,0,canvas.width,canvas.height);
chessImgData.grids.forEach(g=>{//格子上没有棋子,就不绘制if(g.id==undefined) return;let chess = chessImgData.chesses.find(p=>p.id==g.id && p.uid==g.uid);this.drawChess(chess,g);
});
//绘制完成,生成图片,显示到页面上
let base64 = canvas.toDataURL();
ctx.clearRect(0,0,canvas.width,canvas.height);
this.setData({chessesImg:base64
})

上面用到绘制棋子的方法是drawChess(),传入的参数是棋子和格子,可以从格子上绘制棋子

实现移动棋子

讲到这里,不得不说,这里实现用户选择棋子移动的逻辑要复杂一些,看看实现步骤,能否看懂全靠领悟,

从用户开始触摸发生的事件里,根据触摸坐标获取到的指定格子为grid,作为判断,看如下代码,

//上次选择的格子
let selectGrid = this.selectGrid;
//格子上是否有棋子,通过棋子id判断
if (grid.id!=undefined){//uid 是用户id,通过myFlag来指定哪个用户可以下棋if (selectGrid && selectGrid.uid!=undefined && selectGrid.uid==myFlag){//判断不是自己的棋,就吃棋if (grid.uid!=selectGrid.uid){//通过走棋规则方法判断是否可以移动棋子	if (this.isMoveChess(selectGrid,grid)){//置反myFlag方法,自己下棋后,给对方下this.reverseMyFlag(selectGrid.uid);//更新移动棋的数据,貌似没用,实际上是用于吃过路兵判断的this.updateMoveData(selectGrid,grid);//吃棋方法,包括动画逻辑this.takeChess(selectGrid,grid);//判断棋id,若吃掉是对方的王,则游戏结束if(grid.id==1) this.endGame(selectGrid.uid);else if(selectGrid.id==5){//判断兵是否到对方底线,国际象棋的规则:兵升变if((selectGrid.uid==1 && grid.y==0) || (selectGrid.uid!=1 && grid.y==Cols-1)){//弹出选择对话框,玩家要选择把兵变换成其它棋子this.showModalSelectChangeChess(grid);}}return;}else {//国际象棋的规则:吃过路兵const { movedData } = this;//通过之前棋子移动的数据,判断是否吃过路兵if(movedData && movedData.id==grid.id && grid.id==5 && movedData.x2==grid.x && movedData.y2==grid.y && movedData.x1==movedData.x2 && movedData.uid!=selectGrid.uid){let offsetX = 0;//...此处省略了if(offsetX!=0 && selectGrid.y==grid.y){//...此处省略了,这里处理吃掉过路兵this.reverseMyFlag(selectGrid.uid);this.updateMoveData(selectGrid,grid);this.takeChess(selectGrid,grid);}}}}}   
}else{//判断自己的棋子if (selectGrid && selectGrid.uid==myFlag){//是否可以移动if (this.isMoveChess(selectGrid,grid)){this.reverseMyFlag(selectGrid.uid);this.updateMoveData(selectGrid,grid);//移动棋子 产生的动画是异步处理的, 当动画完成时会调用replaceChess() 会将两个格子数据(包括棋子)替换this.moveChess(selectGrid,grid,()=>this.replaceChess(selectGrid,grid));//判断是兵 当前进到对方底线时,就按国际象棋规则 兵升变 处理if(selectGrid.id==5){if((selectGrid.uid==1 && grid.y==0) || (selectGrid.uid!=1 && grid.y==Cols-1)){this.showModalSelectChangeChess(grid);}}return;}//判断是否是王的棋子,是否要朝车方向走,按照国际象棋规则:王车易位 处理else if(selectGrid.x==4 && selectGrid.isUsed!=true && grid.id==undefined && (selectGrid.y==0 || selectGrid.y==Cols-1)){let offsetX=0;let chess;//...此处省略了,判断王棋子是否未使用过,满足王车易位条件if(offsetX!=0 && chess.id==4 && chess.isUsed!=true){//...扫描王前进的路线let scan = () => {//...此处省略了};if(scan()){//可以走了,王和车同时移动,这里会出现两次移动动画效果:王先过去,然后让车过来this.moveChess(selectGrid,grid,()=>{this.reverseMyFlag(selectGrid.uid);//...此处省略了this.updateMoveData(selectGrid,grid);this.moveChess(selectGrid,grid,()=>this.replaceChess(selectGrid,grid));});}}}}
}

以上代码,全是判断逻辑,不要求新手能否看懂,只知道实现思路就好了,
理论上讲得思路是对的,已得到验证是可行的,可以参考一下,自己有能力实现就好

实现下棋规则

下棋规则的判断实现逻辑看似易懂,要通过代码实现就要复杂多了,实现过程需要有耐心,思路要清晰,一步一步来,相信自己,

上面已经讲出 “吃过路兵兵升变王车易位”的规则判断逻辑了,

还有其余的下棋规则,都是交给方法isMoveChess(selectGrid,grid)去处理的,看如下代码

//用point保存一下上次选择的格子坐标
const point = { x:selectGrid.x, y:selectGrid.y };
//定义预测棋子是否可移动的方法
const isMove = (x,y,next) => {point.x = selectGrid.x+x;point.y = selectGrid.y+y;//...此处省略了return false;
};
//根据不同的棋子来判断走棋规则,如果可以走,就返回true;
//对照['后','王','象','马','车','兵'][selectGrid.id]
switch(selectGrid.id){case 0:{//...此处省略了,都与王的走棋大概一致,得看怎么调用isMove()}break;case 1:{//王的走棋规则,是这样的调用的if(isMove(-1,-1)) return true;if(isMove(0,-1)) return true;if(isMove(1,-1)) return true;if(isMove(1,0)) return true;if(isMove(1,1)) return true;if(isMove(0,1)) return true;if(isMove(-1,1))return true;if(isMove(-1,0)) return true;}break;case 2:{//...此处省略了}break;case 3:{//...此处省略了}break;case 4:{//...此处省略了}break;case 5:{//...此处省略了}break;default://其它,打印测试用的,正常的话,是不会执行到此处console.log({ name:ChessNames[selectGrid.id], selectGrid })
}
return false;

从上面代码来看,几乎所有走棋判断都会用到预测棋子是否可移动的方法isMove(x,y,next)

  • 参数xy是相对位置偏移量;
  • 参数next是执行下一步的方法,是递归调用的;

很难理解的话就先放着,等到自己水平提升以后,有好奇心再回来研究弄清楚就好

测试游戏

就讲到这里,小程序项目基本上就算完成了,运行的动图效果如下

在这里插入图片描述

国际象棋-特殊规则:吃过路兵

请添加图片描述

国际象棋-特殊规则:王车易位

其余的细节动图这里就不展示了,从编写实现难度上看,国际象棋是要比中国象棋的实现要复杂一些,原理上大同小异,

想要小程序项目源码请点这里查看,在资源一栏下可找到 国际象棋-小程序项目源码,请放心下载,值得研究学习,感谢支持!


http://chatgpt.dhexx.cn/article/iBJRU1I8.shtml

相关文章

利用C语言巧妙实现棋类游戏——三子棋

小游戏&#xff1a;三子棋用C语言实现 你是否学完了C语言的函数、数组、选择结构、循环结构苦于没有实战小项目巩固自己所学的知识呢&#xff0c;今天小程序猿就给大家带来了一个游戏的小游戏——三子棋&#xff0c;利用C语言实现的&#xff0c;希望对大家能有所帮助。 我们大家…

基于C#的五子棋游戏设计

目 录 一、 毕业设计内容 3 二、 毕业设计目的 3 三、 工具/准备工作 3 四、 设计步骤和方法 3 &#xff08;一&#xff09; 总体设计 3 1&#xff0e; 总体设计思路及设计图 3 2&#xff0e; 界面设计 4 3&#xff0e; 全局变量设计 4 &#xff08;二&#xff09; 详细设计 5 …

【Unity连载】斗兽棋-棋类游戏开发演示(2)

第四章 游戏操作与指令 如同养育一个婴儿&#xff0c;父母总会一步步引领孩子成长&#xff0c;从蹒跚学步到来去如风&#xff1b;我们对游戏功能的开发&#xff0c;也无疑应当从走出第一步棋开始。现在&#xff0c;我们已经构建出了棋盘、棋子等基本的游戏逻辑对象&#xff1b…

Java游戏开发——中国象棋联机版

游戏介绍&#xff1a; 中国象棋是起源于中国的一种棋戏&#xff0c;属于二人对抗性游戏的一种&#xff0c;在中国有着悠久的历史。由于规则简单&#xff0c;趣味性强&#xff0c;成为流行极为广泛的棋类游戏。 中国象棋使用方形格状棋盘及红黑二色圆形棋子进行对弈&#xff0c…

【论文】word中三线表的快速简单制作

【论文】word中三线表的快速简单制作 首先&#xff0c;打开word点击插入→表格&#xff0c;选择需要插入表格的行列数&#xff0c;行列数没有关系&#xff0c;因为你插入后可以随意添加行列。 则插入了一下表格&#xff1a; 把你所需要的数据放进去&#xff1a; 之后&#…

如何在word中制作线宽不同的三线表

在word中难免会插入特定的三线表&#xff0c;那就现场给给大家演示一遍 1、打开word&#xff0c;点击插入&#xff0c;点击表格&#xff0c;至于插入几行几列看自己的需求哈。 2、右键点击表格&#xff0c;然后点击表格属性 3、点击边框和底纹&#xff0c;对表格去除相关边线 …

论文中的三线表绘制(word)

步骤 1、选中表格&#xff08;点击下图中的红框部分选中&#xff09; 2、右击表格选择“表格属性” 3、点击边框和底纹&#xff0c;再选择无边框&#xff08;先不要点确定&#xff09; 4、设置三线表的上下边框&#xff08;1.5磅&#xff09;&#xff0c;完成下图之后点击确定-…

word三线表标题两条线之间如何出现空白间隔(论文必备)

为了写论文&#xff0c;我需要把以上的标题转换成下图所示的样子 所实现的步骤如下&#xff1a; 1、把标题内容回车 放在下一行 2、加一条绘制表格的线 3、选中第一行对应位置的两格&#xff0c;合并单元格 并填入内容 可以看到单纯的加上边框&#xff0c;两条线之间是没有空…

Word 2016表格三线表制作

1、打开word&#xff0c;点击插入&#xff0c;插入一个表格。 2、选中表格&#xff0c;点击设计&#xff0c;在边框中的笔画粗细选择1.5磅&#xff0c;然后在边框下拉框先选择无框线&#xff0c;再选择上框线和下框线。然后笔画粗细选择0.5磅&#xff0c;选中第一行后&#x…

三线表的制作

目录 前言参考过程 前言 最近在写些东西的时候&#xff0c;需要用到三线表&#xff0c;上网查了一下&#xff0c;将方法记录下来。 参考 三分钟快速制作论文三线表 过程 (1) 先插入一个表格&#xff0c;然后新建一个表格样式 (2) 如下图所示更改 (3) 点击第二步中的格式&a…

word表格跨页多出一根线(三线表)

在word中做三线表&#xff0c;表格跨页了自动在页底部加一横线&#xff0c;下一页页首加一横线这个怎么去掉么 首先感谢上方在知乎给出解决方案的博主&#xff0c; 接着&#xff1a;文中描述大概操作如下&#xff1a; 如果还是不行&#xff0c;那么就拿来dou一个三线表

Word插入三线表

在Word中插入一个三线表&#xff0c;方法如下所示&#xff1a; 一、先插入一个正常的表格&#xff0c;并输入好相应的数据 二、单击表格的左上角按钮&#xff0c;选中整个表格 选中表格之后&#xff0c;【右键】-【表格属性】&#xff0c;在弹出的表格属性对话框中单击【边框与…

在Word文档中插入三线表

在Word文档中插入三线表 ①插入一个适合你的文字安排的表格 例如&#xff0c;我要如下情况的示例; 则插入一个五行两列的表格并输入数据; 输完数据之后可以全选表格设置字体 全选表格——边框——边框和底纹&#xff1a; 然后按照下列设置&#xff1a; 结果如下; 然后再…

word 三线表 中间辅助线即行线如何断开?

达到如下图的目的&#xff1a; http://www.dxy.cn/bbs/topic/20891892#opennewwindow http://muchong.com/t-4447061-1 总而言之&#xff0c;最简单易行的方法就是多插入一列&#xff0c;然后去掉该列的边框即可&#xff01;

新建论文三线表模板,一键格式刷

论文三线表模板 写在最前面①表设计&#xff0c;新建表格样式②三线表上下线③三线表标题线④设置表格居中⑤设置表头格式容易出错的步骤 写在最前面 论文写完啦&#xff0c;准备调整格式 之前建模也是三线表&#xff0c;但只能基于该文档模板&#xff0c;所以重新设置一下。 …

针对跨页三线表,在Word2016及以上版本中设置表标题和表头在下一页重复以及解决表格跨页处没有下框线的问题

一、在Word2016及以上版本中设置表标题和表头在下一页重复 技巧1&#xff1a;把标题写在表格里&#xff0c;而不是把标题写在表格外&#xff0c;这样表标题也可以跨页重复啦 操作1&#xff1a;选中上述前两行——右击鼠标——选择“表格属性”——选择“行”——勾选“在各页顶…

【办公】word中实现三线表(跨页,续表)

文章目录 前言三线表生成一张表格设置标题和交叉引用设置三线表选中表格的全部设置边框与底纹 设置跨页分割成两个表设置标题行重复 ⭐ 设置续表标识巧妙用文本框 END 前言 在办公中&#xff0c;一些场景需要将普遍表格设设置为三线表(如&#xff1a;论文) 而很多朋友不知道怎…

如何设置三线表线条的粗细

通常编写学生在编写毕业论文时&#xff0c;常用到三线表&#xff0c;而且三线表的线条粗细需要进行设置&#xff0c;使用word进行线条粗细设置时&#xff0c;经常会出现线条粗细不变的情况&#xff0c;以下使用图文形式说明设置过程。 将word的显示调整为100%&#xff0c;如图…

word制作三线表及保存模板

制作三线表 插入---表格 delete删除表格内容 backspace删除表格 开始菜单下选择有无框线 选中表格---布局---查看网格线&#xff08;无框线下显示表格形状&#xff09; 点击表格---表设计---调整磅数---边框刷刷需要更改的边线 上下1.5磅&#xff0c;中间0.5磅 使行间距…

Word三线表创建

三线表是论文写作中经常使用到的表格格式 自定义三线表 “插入”-->“表格”&#xff0c;随便插入一个表格&#xff0c;然后将光标移动到表格内 “表设计”-->“其他”-->“新建表格样式” 修改模板名称为“三线表”&#xff0c;方便下次直接套用 首先设置标题行【…