• 售前

  • 售后

热门帖子
入门百科

js canvas实现五子棋小游戏

[复制链接]
朗读者72 显示全部楼层 发表于 2021-10-25 20:01:05 |阅读模式 打印 上一主题 下一主题
本文实例为各人分享了canvas实现五子棋小游戏的具体代码,供各人参考,具体内容如下
结果

思路
      
  • canvans 绘制棋盘,绘制时间边沿预留棋子位置  
  • 监听点击变乱绘制落子并纪录到字典中  
  • 得胜判断,在四个方向上检测是否有充足数量的连贯棋子

代码
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <title>ym</title>
  6.   <style>
  7.     canvas {
  8.       display: block;
  9.       margin: 0 auto;
  10.       border: 0
  11.     }
  12.     .result {
  13.       text-align: center;
  14.     }
  15.     button{
  16.       display: block;
  17.       margin: 0 auto;
  18.       padding: 4px 20px;
  19.       border:0;
  20.       color: #fff;
  21.       outline: none;
  22.       border-radius: 3px;
  23.       background: #43a6ff
  24.     }
  25.     button:hover{
  26.       font-weight: bold;
  27.       cursor: pointer;
  28.     }
  29.   </style>
  30. </head>
  31. <body>
  32. <canvas id="cv" width="200px" height="200px"></canvas>
  33. <p class="result"></p>
  34. <button onclick="loadPanel(400, 400,30,13)">刷新</button>
  35. <script>
  36.   loadPanel(400, 400,30,13);
  37.   /**
  38.    * 1) 点击落子并切换执子者
  39.    * 2)以当前落子位置为基准,以‘米'字型判定,是否能构成五连及以上
  40.    * @param w 棋盘宽度
  41.    * @param h 棋盘高度
  42.    * @param cs 格子尺寸
  43.    * @param ps 棋子半径
  44.    */
  45.   function loadPanel(w, h, cs, ps) {
  46.     let i, j, k;
  47.     let chks = [[1, 0], [0, 1], [1, 1], [1, -1]];//水平,纵向,斜下,斜上 四个方向
  48.     let successNum = 5;//赢棋标准
  49.     let resultEl = document.querySelector('.result');
  50.     //1)绘制棋盘,边缘应隔开棋子半径的距离
  51.     cs = cs || 16;//默认格子宽高
  52.     ps = ps || 4;//棋子半径
  53.     h = h || w;//高度默认等于宽度
  54.     let el = document.getElementById('cv');
  55.     el.setAttribute('width', w + 'px');
  56.     el.setAttribute('height', h + 'px');
  57.     let context = el.getContext("2d");
  58.     //计算棋盘分割,向下取整
  59.     let splitX = ~~((w - 2 * ps) / cs), splitY = ~~((h - 2 * ps) / cs);
  60.     //初始化落子位置使用字典存储,相较于数组简单且减少内存占用
  61.     let pieces = {};
  62.     //循环划线
  63.     context.translate(ps, ps);
  64.     context.beginPath();
  65.     context.strokeStyle = '#000';
  66.     //垂直线
  67.     for (i = 0; i < splitX + 1; i++) {
  68.       context.moveTo(cs * i, 0);
  69.       context.lineTo(cs * i, splitY * cs);
  70.       context.stroke();
  71.     }
  72.     //水平线
  73.     for (j = 0; j < splitY + 1; j++) {
  74.       context.moveTo(0, cs * j);
  75.       context.lineTo(splitX * cs, cs * j);
  76.       context.stroke();
  77.     }
  78.     context.closePath();
  79.     let user = 0, colors = ['#000', '#fefefe'];
  80.     el.addEventListener('click', function (e) {
  81.       let x = e.offsetX,
  82.         y = e.offsetY,
  83.         //计算落子范围
  84.         rx = ~~((x - ps) / cs) + (((x - ps) % cs <= cs / 2) ? 0 : 1),
  85.         ry = ~~((y - ps) / cs) + (((y - ps) % cs <= cs / 2) ? 0 : 1);
  86.       //绘制棋子
  87.       context.beginPath();
  88.       context.arc(cs * rx, cs * ry, ps, 2 * Math.PI, false);
  89.       context.fillStyle = colors[user];
  90.       context.strokeStyle = '#000';
  91.       user ? user = 0 : user = 1;//切换执子者
  92.       context.fill();
  93.       context.stroke();
  94.       context.closePath();
  95.       //记录棋子位置
  96.       let piece = pieces[rx + '-' + ry] = user;
  97.       //米字型计算结果,以当前落子位置计算是否存在某个方向上具有连续的五个相同棋子
  98.       for (j = 0; j < chks.length; j++) {
  99.         let num = 1, chk = chks[j];
  100.         for (i = 1; i <= 4; i++) {
  101.           if (pieces[(rx + chk[0] * i) + '-' + (ry + chk[1] * i)] == piece) {
  102.             num++
  103.           } else {
  104.             for (i = -1; i >= -4; i--) {
  105.               if (pieces[(rx + chk[0] * i) + '-' + (ry + chk[1] * i)] == piece) {
  106.                 num++
  107.               }
  108.             }
  109.             break
  110.           }
  111.         }
  112.         if (num == successNum) {
  113.           resultEl.innerHTML = ['白', '黑'][user] + '方赢';
  114.           break;
  115.         }
  116.       }
  117.     })
  118.   }
  119. </script>
  120. </body>
  121. </html>
复制代码
以上就是本文的全部内容,希望对各人的学习有所资助,也希望各人多多支持草根技术分享。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作