js canvas实现五子棋小游戏


Posted in Javascript onJanuary 22, 2021

本文实例为大家分享了canvas实现五子棋小游戏的具体代码,供大家参考,具体内容如下

效果

js canvas实现五子棋小游戏

思路

  • canvans 绘制棋盘,绘制时候边缘预留棋子位置
  • 监听点击事件绘制落子并记录到字典中
  • 获胜判定,在四个方向上检测是否有足够数量的连贯棋子

js canvas实现五子棋小游戏

代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>ym</title>
  <style>
    canvas {
      display: block;
      margin: 0 auto;
      border: 0
    }

    .result {
      text-align: center;
    }
    button{
      display: block;
      margin: 0 auto;
      padding: 4px 20px;
      border:0;
      color: #fff;
      outline: none;
      border-radius: 3px;
      background: #43a6ff
    }
    button:hover{
      font-weight: bold;
      cursor: pointer;
    }
  </style>
</head>
<body>
<canvas id="cv" width="200px" height="200px"></canvas>
<p class="result"></p>
<button onclick="loadPanel(400, 400,30,13)">刷新</button>
<script>

  loadPanel(400, 400,30,13);

  /**
   * 1) 点击落子并切换执子者
   * 2)以当前落子位置为基准,以‘米'字型判定,是否能构成五连及以上
   * @param w 棋盘宽度
   * @param h 棋盘高度
   * @param cs 格子尺寸
   * @param ps 棋子半径
   */
  function loadPanel(w, h, cs, ps) {
    let i, j, k;
    let chks = [[1, 0], [0, 1], [1, 1], [1, -1]];//水平,纵向,斜下,斜上 四个方向
    let successNum = 5;//赢棋标准
    let resultEl = document.querySelector('.result');

    //1)绘制棋盘,边缘应隔开棋子半径的距离
    cs = cs || 16;//默认格子宽高
    ps = ps || 4;//棋子半径
    h = h || w;//高度默认等于宽度

    let el = document.getElementById('cv');
    el.setAttribute('width', w + 'px');
    el.setAttribute('height', h + 'px');
    let context = el.getContext("2d");
    //计算棋盘分割,向下取整
    let splitX = ~~((w - 2 * ps) / cs), splitY = ~~((h - 2 * ps) / cs);

    //初始化落子位置使用字典存储,相较于数组简单且减少内存占用
    let pieces = {};
    //循环划线
    context.translate(ps, ps);
    context.beginPath();
    context.strokeStyle = '#000';
    //垂直线
    for (i = 0; i < splitX + 1; i++) {
      context.moveTo(cs * i, 0);
      context.lineTo(cs * i, splitY * cs);
      context.stroke();
    }
    //水平线
    for (j = 0; j < splitY + 1; j++) {
      context.moveTo(0, cs * j);
      context.lineTo(splitX * cs, cs * j);
      context.stroke();
    }
    context.closePath();

    let user = 0, colors = ['#000', '#fefefe'];
    el.addEventListener('click', function (e) {
      let x = e.offsetX,
        y = e.offsetY,
        //计算落子范围
        rx = ~~((x - ps) / cs) + (((x - ps) % cs <= cs / 2) ? 0 : 1),
        ry = ~~((y - ps) / cs) + (((y - ps) % cs <= cs / 2) ? 0 : 1);
      //绘制棋子
      context.beginPath();
      context.arc(cs * rx, cs * ry, ps, 2 * Math.PI, false);
      context.fillStyle = colors[user];
      context.strokeStyle = '#000';
      user ? user = 0 : user = 1;//切换执子者
      context.fill();
      context.stroke();
      context.closePath();

      //记录棋子位置
      let piece = pieces[rx + '-' + ry] = user;

      //米字型计算结果,以当前落子位置计算是否存在某个方向上具有连续的五个相同棋子
      for (j = 0; j < chks.length; j++) {
        let num = 1, chk = chks[j];
        for (i = 1; i <= 4; i++) {
          if (pieces[(rx + chk[0] * i) + '-' + (ry + chk[1] * i)] == piece) {
            num++
          } else {
            for (i = -1; i >= -4; i--) {
              if (pieces[(rx + chk[0] * i) + '-' + (ry + chk[1] * i)] == piece) {
                num++
              }
            }
            break
          }
        }
        if (num == successNum) {
          resultEl.innerHTML = ['白', '黑'][user] + '方赢';
          break;
        }
      }
    })
  }
</script>
</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
常用参考资料(手册)下载或者链接
Jul 22 Javascript
Mootools 1.2教程(3) 数组使用简介
Sep 14 Javascript
jQuery操作select的实例代码
Jun 14 Javascript
使用jquery动态加载javascript以减少服务器压力
Oct 29 Javascript
选择器中含有空格在使用示例及注意事项
Jul 31 Javascript
jQuery获取当前对象标签名称的方法
Feb 07 Javascript
DOM节点深度克隆函数cloneNode()用法实例
Jan 12 Javascript
JS实现的不规则TAB选项卡效果代码
Sep 18 Javascript
jQuery实现HTML表格单元格的合并功能
Apr 06 Javascript
bootstrapValidator.min.js表单验证插件
Feb 09 Javascript
VUE2.0+ElementUI2.0表格el-table循环动态列渲染的写法详解
Nov 30 Javascript
2分钟实现一个Vue实时直播系统的示例代码
Jun 05 Javascript
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
Jan 22 #Vue.js
element-ui 弹窗组件封装的步骤
Jan 22 #Javascript
动态实现element ui的el-table某列数据不同样式的示例
Jan 22 #Javascript
原生js实现放大镜组件
Jan 22 #Javascript
Vue仿Bibibili首页的问题
Jan 21 #Vue.js
如何在vue 中使用柱状图 并自修改配置
Jan 21 #Vue.js
Vue看了就会的8个小技巧
Jan 21 #Vue.js
You might like
PHP json格式和js json格式 js跨域调用实现代码
2012/09/08 PHP
php使用异或实现的加密解密实例
2013/09/04 PHP
php实现的数字验证码及数字运算验证码
2015/07/30 PHP
php 访问oracle 存储过程实例详解
2017/01/08 PHP
php过滤输入操作之htmlentities与htmlspecialchars用法分析
2017/02/17 PHP
ThinkPHP模板标签eq if 中区分0,null,false的方法
2017/03/24 PHP
php mysql_list_dbs()函数用法示例
2017/03/29 PHP
使用Zookeeper分布式部署PHP应用程序
2019/03/15 PHP
php中使用array_filter()函数过滤数组实例讲解
2021/03/03 PHP
两个数组去重的JS代码
2013/12/04 Javascript
解析JSON对象与字符串之间的相互转换
2013/12/18 Javascript
原生javascript实现图片滚动、延时加载功能
2015/01/12 Javascript
js网页滚动条滚动事件实例分析
2015/05/05 Javascript
简单分析javascript面向对象与原型
2015/05/21 Javascript
基于jquery实现导航菜单高亮显示(两种方法)
2015/08/23 Javascript
JS中setTimeout的巧妙用法前端函数节流
2016/03/24 Javascript
JS封装的三级联动菜单(使用时只需要一行js代码)
2016/10/24 Javascript
基于jQuery实现照片墙自动播放特效
2017/01/12 Javascript
老生常谈combobox和combotree模糊查询
2017/04/17 Javascript
NodeJs中express框架的send()方法简介
2017/06/20 NodeJs
Node.js简单入门前传
2017/08/21 Javascript
详解js动态获取浏览器或页面等容器的宽高
2019/03/13 Javascript
Angular7中创建组件/自定义指令/管道的方法实例详解
2019/04/02 Javascript
[00:47]DOTA2荣耀之路6:玩不了啦!
2018/05/30 DOTA
[01:00:49]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第二场 1月31日
2021/03/11 DOTA
详解Python的Twisted框架中reactor事件管理器的用法
2016/05/25 Python
Python3.8中使用f-strings调试
2019/05/22 Python
如何用Python破解wifi密码过程详解
2019/07/12 Python
Pyspark读取parquet数据过程解析
2020/03/27 Python
Python如何把字典写入到CSV文件的方法示例
2020/08/23 Python
汽车制造与装配专业自荐信范文
2014/01/02 职场文书
办理退休介绍信
2014/01/09 职场文书
函授毕业生自我鉴定范文
2014/03/25 职场文书
高中数学教学反思范文
2016/02/18 职场文书
给原生html中添加水印遮罩层的实现示例
2021/04/02 Javascript
Requests什么的通通爬不了的Python超强反爬虫方案!
2021/05/20 Python