微信小程序五子棋游戏的棋盘,重置,对弈实现方法【附demo源码下载】


Posted in Javascript onFebruary 20, 2019

本文实例讲述了微信小程序五子棋游戏的棋盘,重置,对弈实现方法。分享给大家供大家参考,具体如下:

DEMO下载

效果图

微信小程序五子棋游戏的棋盘,重置,对弈实现方法【附demo源码下载】

分析

1. 采用微信小程序的canvas制作五子棋;
2. 确定棋盘大小及格数;
3. 绘制棋盘—-通过棋盘宽高和格数计算间距,同时保存坐标点;
4. 黑方和白方下子—-定义一个布尔变量代表各自的身份;
5. 重置棋盘—-重新开始;
6. 通过判断当前棋手,悔棋时进行改变。

绘制棋盘

drawLine(arr){
 arr.forEach(current => {
  this.ctx.setFillStyle(this.lineColor);
  this.ctx.beginPath();
  this.ctx.lineWidth = 1;
  this.ctx.moveTo(current[0].x, current[0].y);
  for (var i = 1; i < current.length; i++) {
  this.ctx.lineTo(current[i].x, current[i].y);
  }
  this.ctx.stroke();
  this.ctx.closePath();
  this.ctx.draw(true);
 });
 }
 drawChessboard(){
 // 每个格子的宽高
 var everyLen = this.everyLen;
 // 标记坐标的个数
 var count = 0;
 // 从纵向保存坐标
 var arrY = [];
 // 双循环计算每个坐标的横纵坐标
 for(var i = 0;i <= this.type; i++){
  var arr = [],arr0 = [];
  for(var j = 0;j <= this.type; j++){
  count++;
  arr.push({
   y: this.margin + i * everyLen,
   x: this.margin + j * everyLen,
   pointX: j,
   pointY: i,
   index: count
  });
  arr0.push({
   x: this.margin + i * everyLen,
   y: this.margin + j * everyLen
  })
  }
  // 清空canvas
  this.ctx.clearRect(0, 0, this.width, this.height);
  // 保存横线坐标和竖线坐标
  this.everyPoint.push(arr);
  arrY.push(arr0);
 }
 // 绘制横向线
 this.drawLine(this.everyPoint);
 // 绘制竖向线
 this.drawLine(arrY);
 }

绘制当前点击坐标的棋子

// 获取当前点击位置的坐标
 getPosition(e){
 return {
  x: e.touches[0].x,
  y: e.touches[0].y
 };
 }
 // 将当前坐标和棋盘坐标数组对比,找到精确坐标
 checkPoint(arr,po){
 for (var i = 0; i < this.everyPoint.length; i++){
  for (var j = 0; j < this.everyPoint[i].length; j++){
  if (Math.abs(this.everyPoint[i][j].x - po.x) < this.everyLen/2 && Math.abs(this.everyPoint[i][j].y - po.y) < this.everyLen/2){
   // 将棋盘精确坐标保存到当前持棋方数组
   arr.push(this.everyPoint[i][j]);
   // 同时删除棋盘坐标数组的该值,表示当前位置已经存在棋子
   this.everyPoint[i].splice(j,1);
   break;
  }
  }
 }
 }
 // 绘制当前坐标棋子
 drawCle(opts,color){
 this.ctx.setFillStyle(color);
 this.ctx.beginPath();
 this.ctx.arc(opts.x, opts.y, this.r, 0, Math.PI * 2, true);
 this.ctx.closePath();
 this.ctx.fill();
 this.ctx.draw(true);
 }
 drawLastPoint(type){
 // 判断是黑方持棋还是白方持棋,进行绘制棋子
 if(type == 'AI'){
  this.AIPoint.forEach((current, index) => {
  this.drawCle(current, '#000000');
  });
 }else{
  this.myPoint.forEach((current, index) => {
  this.drawCle(current, '#ffffff');
  });
 }
 }
 this.page.changeTouchStart = function (e) {
  // 判断游戏是否开始
  if (self.START_GAME){
  // 获取当前坐标
  var newPo = self.getPosition(e);
  // 获取棋盘精确坐标
  if (!self.boolAI && self.boolMy) {
   self.checkPoint(self.myPoint, newPo);
  } else if (self.boolAI && !self.boolMy) {
   self.checkPoint(self.AIPoint, newPo);
  }
  }
 }
 this.page.changeTouchEnd = function (e) {
  if (self.START_GAME) {
  // 绘制棋子
  if (!self.boolAI && self.boolMy) {
   self.boolAI = !self.boolAI;
   self.boolMy = !self.boolMy;
   self.drawLastPoint('PO');
   // 判断白棋是否五子胜利
   if (self.myPoint.length >= 5 && self.checkWinner(self.myPoint)){
   wx.showToast({title: '白棋胜利!'});
   self.START_GAME = false;
   }
  } else if (self.boolAI && !self.boolMy) {
   self.boolAI = !self.boolAI;
   self.boolMy = !self.boolMy;
   self.drawLastPoint('AI');
   // 判断黑棋是否五子胜利
   if(self.AIPoint.length >= 5 && self.checkWinner(self.AIPoint)){
   wx.showToast({ title: '黑棋胜利!' });
   self.START_GAME = false;
   }
  }
  }
 }

五子棋胜利方判断

五子棋胜利就是横向、纵向、45度斜线方向、135度斜线方向连成五个颜色相同的棋子,为了更加清楚的表示,我将四个方向的判断做四个函数处理。

checkTransverse(arr,po){//横向检查
 var len = arr.length - 1;
 var count = 1;
 // 东
 for(var i = 1; i < this.CHESS_LEN ; i++){
  for (var j = 0; j < len; j++){
  if(arr[j].pointX == po.pointX - i && arr[j].pointY == po.pointY){
   count++;
  }
  }
 }
 if (count == this.CHESS_LEN) { return true;}
 // 西
 for (var i = 1; i < this.CHESS_LEN; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointX == po.pointX + i && arr[j].pointY == po.pointY) {
   count++;
  }
  }
 }
 if (count == this.CHESS_LEN) { return true; }
 }
 checkPortrait(arr,po){//纵向检查
 var len = arr.length - 1;
 var count = 1;
 // 南
 for (var i = 1; i < this.CHESS_LEN; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointX == po.pointX && arr[j].pointY == po.pointY - i) {
   count++;
  }
  }
 }
 if (count == this.CHESS_LEN) { return true; }
 // 北
 for (var i = 1; i < this.CHESS_LEN; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointX == po.pointX && arr[j].pointY == po.pointY + i) {
   count++;
  }
  }
 }
 if (count == this.CHESS_LEN) { return true; }
 }
 checkNortheast(arr,po){//45度
 var len = arr.length - 1;
 var count = 1;
 // 西南
 for (var i = 1; i < this.CHESS_LEN; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointX == po.pointX - i && arr[j].pointY == po.pointY - i) {
   count++;
  }
  }
 }
 if (count == this.CHESS_LEN) { return true; }
 // 东北
 for (var i = 1; i < this.CHESS_LEN; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointX == po.pointX + i && arr[j].pointY == po.pointY + i) {
   count++;
  }
  }
 }
 if (count == this.CHESS_LEN) { return true; }
 }
 checkNorthwest(arr,po){//135度
 var len = arr.length - 1;
 var count = 1;
 // 西北
 for (var i = 1; i < this.CHESS_LEN; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointX == po.pointX - i && arr[j].pointY == po.pointY + i) {
   count++;
  }
  }
 }
 if (count == this.CHESS_LEN) { return true; }
 // 东南
 for (var i = 1; i < this.CHESS_LEN; i++) {
  for (var j = 0; j < len; j++) {
  if (arr[j].pointX == po.pointX + i && arr[j].pointY == po.pointY - i) {
   count++;
  }
  }
 }
 if (count == this.CHESS_LEN) { return true; }
 }
 checkWinner(arr){
 var currentPo = arr[arr.length - 1];
 var win1 = this.checkTransverse(arr, currentPo);
 var win2 = this.checkPortrait(arr, currentPo);
 var win3 = this.checkNortheast(arr, currentPo);
 var win4 = this.checkNorthwest(arr, currentPo);
 if (win1 || win2 || win3 || win4){
  return true;
 }else{
  return false;
 }
 }

重置棋盘

resetChessBoard(){
 this.page.setData({ isHide: false });
 this.init();
}
this.page.changeReset = function(e){
 self.resetChessBoard();
}

注意

1. 绘制棋盘前必须清空canvas,方便最后的重新开始和重置棋盘;
2. 对当前棋子的坐标四个方向的判断,采用的原始坐标而不是计算后的绘制坐标;
3. 在判断持棋人时,各自采用一个值,方便添加悔棋功能。

只是实现了简单的对下五子棋功能,后续添加悔棋、记分、记时等功能!

同时向判断胜利的函数可以合并为一进行优化!

希望本文所述对大家微信小程序开发有所帮助。

Javascript 相关文章推荐
跟着JQuery API学Jquery 之二 属性
Apr 09 Javascript
JavaScript基本编码模式小结
May 23 Javascript
JS获取当前日期和时间的简单实例
Nov 19 Javascript
JS实现弹出浮动窗口(支持鼠标拖动和关闭)实例详解
Aug 06 Javascript
jquery实现input框获取焦点的简单实例
Jan 26 Javascript
浅谈angularjs依赖服务注入写法的注意点
Apr 24 Javascript
vue子父组件通信的实现代码
Jul 09 Javascript
Angularjs的启动过程分析
Jul 18 Javascript
Vue实现typeahead组件功能(非常靠谱)
Aug 26 Javascript
vue项目中使用axios上传图片等文件操作
Nov 02 Javascript
js常见遍历操作小结
Jun 06 Javascript
Vue的路由及路由钩子函数的实现
Jul 02 Javascript
详解关于element级联选择器数据回显问题
Feb 20 #Javascript
JavaScript ES2019中的8个新特性详解
Feb 20 #Javascript
echarts实现词云自定义形状的示例代码
Feb 20 #Javascript
JS拖拽排序插件Sortable.js用法实例分析
Feb 20 #Javascript
详解webpack 最简打包结果分析
Feb 20 #Javascript
jQuery表单元素过滤选择器用法实例分析
Feb 20 #jQuery
jQuery内容过滤选择器与子元素过滤选择器用法实例分析
Feb 20 #jQuery
You might like
Access数据库导入Mysql的方法之一
2006/10/09 PHP
[原创]php token使用与验证示例【测试可用】
2017/08/30 PHP
浅谈laravel-admin的sortable和orderby使用问题
2019/10/03 PHP
doctype后如何获得body.clientHeight的方法
2007/07/11 Javascript
JavaScript 以对象为索引的关联数组
2010/05/19 Javascript
表单类各种类型(文本框)失去焦点效果jquery代码
2013/04/26 Javascript
Jquery插件分享之气泡形提示控件grumble.js
2014/05/20 Javascript
JQuery设置获取下拉菜单某个选项的值(比较全)
2014/08/05 Javascript
JavaScript charCodeAt方法入门实例(用于取得指定位置字符的Unicode编码)
2014/10/17 Javascript
node.js中的buffer.fill方法使用说明
2014/12/14 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 简史
2015/01/09 Javascript
Javascript中常见的逻辑题和解决方法
2016/09/17 Javascript
JavaScript 身份证号有效验证详解及实例代码
2016/10/20 Javascript
JS中位置与大小的获取方法
2016/11/22 Javascript
从零开始学习Node.js系列教程之基于connect和express框架的多页面实现数学运算示例
2017/04/13 Javascript
Angularjs根据json文件动态生成路由状态的实现方法
2017/04/17 Javascript
详解React 16 中的异常处理
2017/07/28 Javascript
React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析
2020/01/06 Javascript
使用Python获取Linux系统的各种信息
2014/07/10 Python
简单解决Python文件中文编码问题
2015/11/22 Python
Python使用filetype精确判断文件类型
2017/07/02 Python
Python+OpenCV让电脑帮你玩微信跳一跳
2018/01/04 Python
30秒轻松实现TensorFlow物体检测
2018/03/14 Python
Python最小二乘法矩阵
2019/01/02 Python
对于Python深浅拷贝的理解
2019/07/29 Python
python实现自动化报表功能(Oracle/plsql/Excel/多线程)
2019/12/02 Python
Pytorch中.new()的作用详解
2020/02/18 Python
python:删除离群值操作(每一行为一类数据)
2020/06/08 Python
python基本算法之实现归并排序(Merge sort)
2020/09/01 Python
迪奥官网:Dior.com
2018/12/04 全球购物
英国第一的市场和亚马逊替代品:OnBuy
2019/03/16 全球购物
学生党员的自我评价范文
2014/03/01 职场文书
办公自动化专业大学生职业规划书
2014/03/06 职场文书
捐款感谢信
2015/01/20 职场文书
党员自我评价范文2015
2015/03/03 职场文书
紧急通知
2015/04/17 职场文书