欢迎光临,了解微信小程序开发,就上易用通!

当前位置 : 易用通 > 小程序模板
五子棋,基于canvas五子棋,基于canvas
立即下载

五子棋,基于canvas

模板分类 : 小程序模板 模板编号 : Y252 源码文件 : 完全开源 下载权限 : VIP会员
模板大小 :  模板指数 :  更新时间 : 2018-01-16 17:19 模板等级 : ☆☆☆☆☆

模板截图:

五子棋,基于canvas(图1)  代码示例:
  1. var Stone = require('Stone');
  2. var judger = require('FiveStoneJudger');
  3.  
  4. /**
  5. * 五子棋的主控制类
  6. */
  7. export default class FiveStone {
  8.  
  9.     /**
  10.      * 初始化棋盘
  11.      * @param   page                    当前页面页面
  12.      * @param   chessBoardSize          当前棋盘每行和列最多能下多少个子子
  13.      * @param   chessboardSizePercent   棋盘的宽度相当于屏幕宽度的百分比(0<x<1)
  14.      */
  15.     constructor(chessBoardSize, chessboardSizePercent) {
  16.         var self = this;
  17.         var chessBoard = [];
  18.         //占位
  19.         var chessBoardCell = [];
  20.         this.chessBoardSize = chessBoardSize;
  21.         for (var r = 0; r < chessBoardSize; r++) {
  22.             var row = [];
  23.             var cellRow = [];
  24.             for (var c = 0; c < chessBoardSize; c++) {
  25.                 row.push({
  26.                     stoneType:Stone.none,
  27.                     //位置使用到的时候才计算
  28.                     pos:null
  29.                 });
  30.                 if (c < chessBoardSize - 1) {
  31.                     cellRow.push(0);
  32.                 }
  33.             }
  34.             chessBoard.push(row);
  35.             if (r < chessBoardSize - 1) {
  36.                 chessBoardCell.push(cellRow);
  37.             }
  38.         }
  39.         this.chessBoard = chessBoard;
  40.         this.chessBoardCell = chessBoardCell;
  41.         //获取系统信息
  42.         wx.getSystemInfo({
  43.             success: function(res) {
  44.                 self.chessboardSizePX = res.windowWidth * chessboardSizePercent;
  45.                 console.log('%c棋盘大小:%c' +
  46.                  self.chessboardSizePX +
  47.                   '%cpx',
  48.                   'color:red;',
  49.                   'color:blue;',
  50.                   'color:black;'
  51.                   );
  52.                 self.cellSizePX = self.chessboardSizePX / (chessBoardSize - 1);
  53.                 console.log('%c单元格大小:%c' +
  54.                  self.cellSizePX +
  55.                   '%cpx',
  56.                   'color:red;',
  57.                   'color:blue;',
  58.                   'color:black;'
  59.                   );
  60.                   self.halfCellSizePX = self.cellSizePX * 0.5;
  61.             }
  62.         });
  63.         //当前下子的类型
  64.         this.stone = Stone.black;
  65.         //下子监听的回调集合
  66.         this.onStepStoneCallbacks = [];
  67.         //是否能够下子的开关
  68.         this._canStep = true;
  69.         //历史
  70.         this.history = [];
  71.         //设置裁判
  72.         this.setJudger(judger);
  73.     }
  74.  
  75.     /**
  76.      * 通过事件获取下子在棋盘的位置
  77.      */
  78.     getStepLocation(e) {
  79.         var curTarget = e.currentTarget;
  80.         var offset = {
  81.             x: curTarget.offsetLeft,
  82.             y: curTarget.offsetTop
  83.         };
  84.         var touch = e.touches[0];
  85.         //相对棋盘的位置
  86.         var clientPos = {
  87.             x:touch.pageX - offset.x,
  88.             y:touch.pageY - offset.y
  89.         };
  90.         var stepPos = {
  91.             x: Math.ceil((clientPos.x - this.halfCellSizePX) / this.cellSizePX),
  92.             y: Math.ceil((clientPos.y - this.halfCellSizePX) / this.cellSizePX)
  93.         };
  94.         if (stepPos.x < 0 || stepPos.x >= this.chessBoardSize ||
  95.             stepPos.y < 0 || stepPos.y >= this.chessBoardSize) {
  96.                 return null;
  97.             }
  98.         return stepPos;
  99.     }
  100.  
  101.     /**
  102.      * 通过事件获取下子在棋盘的绝对位置
  103.      */
  104.     getStepPosition(e) {
  105.         var curTarget = e.currentTarget;
  106.         var stepPos = this.getStepLocation(e);
  107.         if (stepPos == null) {
  108.             return null;
  109.         }
  110.         var absPos = stepPos.clone();
  111.         //后面的那个1像素怎么出来的我也不知道,反正减了之后位置看起来正很多
  112.         absPos.x = absPos.x * this.cellSizePX + curTarget.offsetLeft - this.halfCellSizePX - 1;
  113.         absPos.y = absPos.y * this.cellSizePX + curTarget.offsetTop - this.halfCellSizePX - 1;
  114.         this.chessBoard[stepPos.x][stepPos.y].pos = absPos.clone();
  115.         return absPos;
  116.     }
  117.  
  118.     /**
  119.      * 下棋,设置的是基于棋盘的坐标
  120.      * @return  返回true就是下子成功,否则为失败
  121.      */
  122.     step(x, y) {
  123.         if (this.canStepAt(x, y)) {
  124.             this.chessBoard[x][y].stoneType = this.nowStone();
  125.             const nowStone = this.nowStone();
  126.             this.stone = nowStone == Stone.black ? Stone.white:Stone.black;
  127.             this.onStepStone(nowStone, x, y);
  128.  
  129.             if (!(this.history instanceof Array)) {
  130.                 this.history = [];
  131.             }
  132.             //插入到历史
  133.             this.history.push({
  134.                 'x':x,
  135.                 'y':y,
  136.                 'stoneType':nowStone
  137.             });
  138.             this.judge(nowStone, x, y);
  139.             return true;
  140.         }
  141.         return false;
  142.     }
  143.  
  144.     /**
  145.      * 悔棋
  146.      */
  147.     undo() {
  148.         if (!(this.history instanceof Array) || this.history.length <= 0) {
  149.             return;
  150.         }
  151.         const lastStoneIndex = this.history.length - 1;
  152.         const lastStone = this.history[lastStoneIndex];
  153.         this.stone = lastStone.stoneType;
  154.         this.history.splice(lastStoneIndex, 1);
  155.         this.chessBoard[lastStone.x][lastStone.y].stoneType = Stone.none;
  156.         this.allowStep();
  157.     }
  158.  
  159.     /**
  160.      * 判断该棋子是否能够下
  161.      */
  162.     canStepAt(x, y) {
  163.         if (x < 0 || x >= this.chessBoardSize ||
  164.             y < 0 || y >= this.chessBoardSize ||
  165.             this.chessBoard[x][y].stoneType != Stone.none) {
  166.                 return false;
  167.         }
  168.         return this._canStep;
  169.     }
  170.  
  171.     /**
  172.      * 当触发了下子的事件的时候
  173.      */
  174.     onStepStone(nowStone, x, y) {
  175.         if (this.onStepStoneCallbacks instanceof Array) {
  176.             for (var i in this.onStepStoneCallbacks) {
  177.                 const cb = this.onStepStoneCallbacks[i];
  178.                 if (typeof(cb) === 'function') {
  179.                     cb.call(this, nowStone, x, y);
  180.                 }
  181.             }
  182.         }
  183.     }
  184.  
  185.     /**
  186.      * 添加下子的监听器
  187.      * @return 如果返回0则代表插入失败,成功返回索引
  188.      */
  189.     addOnStepStoneCallback(func) {
  190.         if (!(this.onStepStoneCallbacks instanceof Array)) {
  191.             this.onStepStoneCallbacks = [];
  192.         }
  193.         if (typeof(func) == 'function') {
  194.             //push以后会返回数组的长度,所以减一之后就会是对应的索引
  195.             return this.onStepStoneCallbacks.push(func) - 1;
  196.         }
  197.         return 0;
  198.     }
  199.  
  200.     /**
  201.      * 通过索引删除下子的监听器
  202.      */
  203.     removeOnStepStoneCallback(index) {
  204.         if (this.onStepStoneCallbacks instanceof Array) {
  205.             if (this.onStepStoneCallbacks.length > index) {
  206.                 this.onStepStoneCallbacks.splice(index, 1);
  207.             }
  208.         }
  209.     }
  210.  
  211.     /**
  212.      * 重新开局
  213.      */
  214.     restart() {
  215.         this.stone = Stone.black;
  216.         for (var r in this.chessBoard) {
  217.             for (var c in this.chessBoard[r]) {
  218.                 this.chessBoard[r][c].stoneType = Stone.none;
  219.             }
  220.         }
  221.         //清空历史
  222.         this.history = [];
  223.         this.allowStep();
  224.     }
  225.  
  226.     /**
  227.      * 阻止下子
  228.      */
  229.     preventStep() {
  230.         this._canStep = false;
  231.     }
  232.  
  233.     /**
  234.      * 允许下子
  235.      */
  236.     allowStep() {
  237.         this._canStep = true;
  238.     }
  239.  
  240.     /**
  241.      * 获取当前是下的黑子还是白子
  242.      */
  243.     nowStone() {
  244.         return this.stone;
  245.     }
  246.  
  247.     /**
  248.      * 返回当前是否允许下子
  249.      */
  250.     canStep() {
  251.         return this._canStep;
  252.     }
  253.  
  254.     /**
  255.      * 进行裁判(下子成功之后触发)
  256.      * @param stepStone 当前下子的类型
  257.      * @param x         下子基于棋盘的x坐标
  258.      * @param y         下子基于棋盘的y坐标
  259.      */
  260.     judge(stepStone, x, y) {
  261.         if (typeof(this._judger) == 'function') {
  262.             this._judger.call(this, stepStone, x, y, this._winCallback);
  263.         }
  264.     }
  265.  
  266.     /**
  267.      * 设置裁判回调
  268.      */
  269.     setJudger(func) {
  270.         if (typeof(func) == 'function') {
  271.             this._judger = func;
  272.         }
  273.     }
  274.  
  275.     /**
  276.      * 设置胜利之后的回调
  277.      */
  278.     setWinCallback(func) {
  279.         if (typeof(func) == 'function') {
  280.             this._winCallback = func;
  281.         }
  282.     }
  283. }
复制代码

加入收藏
立即下载
分享到微信朋友圈
X

免责声明:

1. 本站所有素材(未指定商用),仅限学习交流,请勿用于商业用途。
2. 本站所有小程序模板Demo和图片均来自用户分享上传和网络收集,模板和图片版权归原作者及原出处所有。
3. 未经合法授权,会员不得以任何形式发布、传播、复制、转售该素材。