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 相关文章推荐
JavaScript使用prototype定义对象类型(转)[
Dec 22 Javascript
jquery 结合C#后台的数组对文章的关键字自动添加链接的代码
Jul 15 Javascript
Javascript 垃圾收集机制介绍理解
May 14 Javascript
jQuery的live()方法对hover事件的处理示例
Feb 27 Javascript
Jquery之Bind方法参数传递与接收的三种方法
Jun 24 Javascript
node.js中的fs.lstat方法使用说明
Dec 16 Javascript
jQuery实现页面点击后退弹出提示框的方法
Aug 24 Javascript
Bootstrap源码解读模态弹出框(11)
Dec 28 Javascript
详解Vue方法与事件
Mar 09 Javascript
jQuery实现切换隐藏与显示同时切换图标功能
Oct 29 jQuery
Vue中使用webpack别名的方法实例详解
Jun 19 Javascript
Vue-Cli 3.0 中配置高德地图的两种方式
Jun 19 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递归删除目录下的文件但保留的实例分享
2014/05/10 PHP
php过滤html标记属性类用法实例
2014/09/23 PHP
PHP+ajax分页实例简析
2015/12/07 PHP
详解在PHP的Yii框架中使用行为Behaviors的方法
2016/03/18 PHP
如何通过View::first使用Laravel Blade的动态模板详解
2017/09/21 PHP
Laravel 5.4因特殊字段太长导致migrations报错的解决
2017/10/22 PHP
PHP异步进程助手async-helper
2018/02/05 PHP
JS弹出对话框返回值代码(asp.net后台)
2010/12/28 Javascript
javascript中call,apply,bind的用法对比分析
2015/02/12 Javascript
AngularJS的一些基本样式初窥
2015/07/27 Javascript
基于HTML+CSS,jQuery编写的简易计算器后续(添加了键盘监听)
2016/01/05 Javascript
基于jquery实现ajax无刷新评论
2020/08/19 Javascript
jQuery EasyUI基础教程之EasyUI常用组件(推荐)
2016/07/15 Javascript
Bootstrap按钮组实例详解
2017/07/03 Javascript
vue awesome swiper异步加载数据出现的bug问题
2018/07/03 Javascript
详解React native fetch遇到的坑
2018/08/30 Javascript
使用异步组件优化Vue应用程序的性能
2019/04/28 Javascript
layui-select动态选中值的例子
2019/09/23 Javascript
Js和VUE实现跑马灯效果
2020/05/25 Javascript
[01:01:25]DOTA2上海特级锦标赛B组资格赛#2 Fnatic VS Spirit第三局
2016/02/27 DOTA
Python语法快速入门指南
2015/10/12 Python
Python中文件的写入读取以及附加文字方法
2019/01/23 Python
将数据集制作成VOC数据集格式的实例
2020/02/17 Python
Python可以用来做什么
2020/11/23 Python
运行python提示no module named sklearn的解决方法
2020/11/29 Python
Python如何使用神经网络进行简单文本分类
2021/02/25 Python
女士时装鞋:Chinese Laundry
2018/08/29 全球购物
Guess欧洲官网:美国服饰品牌
2019/08/06 全球购物
C#笔试题
2015/07/14 面试题
市场部经理岗位职责
2014/04/10 职场文书
小学教师师德承诺书
2014/05/23 职场文书
工作检讨书怎么写
2015/01/23 职场文书
委托书格式范文
2015/01/28 职场文书
公司管理制度范本
2015/08/03 职场文书
厉害!这是Redis可视化工具最全的横向评测
2021/07/15 Redis
详解Vue项目的打包方式(生成dist文件)
2022/01/18 Vue.js