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 相关文章推荐
实测jquery data()如何存值
Aug 18 Javascript
javascript实现促销倒计时+fixed固定在底部
Sep 18 Javascript
JS判断客户端是手机还是PC的2个代码
Apr 12 Javascript
js实现class样式的修改、添加及删除的方法
Jan 20 Javascript
简介AngularJS中使用factory和service的方法
Jun 17 Javascript
基于javascript bootstrap实现生日日期联动选择
Apr 07 Javascript
JavaScript中的工厂函数(推荐)
Mar 08 Javascript
使用vue.js编写蓝色拼图小游戏
Mar 17 Javascript
详解Vue文档中几个易忽视部分的剖析
Mar 24 Javascript
基于iview的router常用控制方式
May 30 Javascript
微信小程序实现点击效果
Jun 21 Javascript
JS window对象简单操作完整示例
Jan 14 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+swoole实现简单多人在线聊天群发
2016/01/19 PHP
jquery 框架使用教程 AJAX篇
2009/10/11 Javascript
Jquery 学习笔记(一)
2009/10/13 Javascript
jQuery之选项卡的简单实现
2014/02/28 Javascript
jQuery原型属性和原型方法详解
2015/07/07 Javascript
JS实现的另类手风琴效果网页内容切换代码
2015/09/08 Javascript
Javascript原型链的原理详解
2016/01/05 Javascript
在IE8上JS实现combobox支持拼音检索功能
2016/05/23 Javascript
Vue.js报错Failed to resolve filter问题的解决方法
2016/05/25 Javascript
Listloading.js移动端上拉下拉刷新组件
2016/08/04 Javascript
详解javascript事件绑定使用方法
2016/10/20 Javascript
NodeJs的fs读写删除移动监听
2017/04/28 NodeJs
vue 音乐App QQ音乐搜索列表最新接口跨域设置方法
2018/09/25 Javascript
详解key在Vue列表渲染时究竟起到了什么作用
2019/04/20 Javascript
Vue中的循环及修改差值表达式的方法
2019/08/29 Javascript
Postman环境变量全局变量使用方法详解
2020/08/13 Javascript
简单的Python2.7编程初学经验总结
2015/04/01 Python
Python实现各种排序算法的代码示例总结
2015/12/11 Python
Python爬虫 批量爬取下载抖音视频代码实例
2019/08/16 Python
python 使用opencv 把视频分割成图片示例
2019/12/12 Python
Python利用FFT进行简单滤波的实现
2020/02/26 Python
浅谈Django QuerySet对象(模型.objects)的常用方法
2020/03/28 Python
Python实现一个简单的递归下降分析器
2020/08/01 Python
python3.8.3安装教程及环境配置的详细教程(64-bit)
2020/11/28 Python
python asyncio 协程库的使用
2021/01/21 Python
html5小技巧之通过document.head获取head元素
2014/06/04 HTML / CSS
Html5踩坑记之mandMobile使用小记
2020/04/02 HTML / CSS
中国最大隐形眼镜网上商城:视客眼镜网
2016/10/30 全球购物
澳大利亚宠物食品和用品商店:PETstock
2020/01/02 全球购物
我能否用void** 指针作为参数, 使函数按引用接受一般指针
2013/02/16 面试题
什么是Web Service?
2012/07/25 面试题
预备党员自我批评思想汇报
2014/10/10 职场文书
起诉书格式范文
2015/05/20 职场文书
委托收款证明
2015/06/23 职场文书
2016年毕业实习心得体会范文
2015/10/09 职场文书
HR必备:销售经理聘用合同范本
2019/08/21 职场文书