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:void(0)是什么意思示例介绍
Nov 17 Javascript
基于jquery扩展漂亮的下拉框可以二次修改
Nov 19 Javascript
jQuery的DOM操作之删除节点示例
Jan 03 Javascript
jQuery实时显示鼠标指针位置和键盘ASCII码
Mar 28 Javascript
jQuery中map函数的两种方式
Apr 07 jQuery
vue 不使用select实现下拉框功能(推荐)
May 17 Javascript
jQuery 实现倒计时天,时,分,秒功能
Jul 31 jQuery
vue form 表单提交后刷新页面的方法
Sep 04 Javascript
Node.js+ELK日志规范的实现
May 23 Javascript
Vue Router 实现动态路由和常见问题及解决方法
Mar 06 Javascript
Jquery高级应用Deferred对象原理及使用实例
May 28 jQuery
vue ant design 封装弹窗表单的使用
Jun 01 Vue.js
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 信息采集程序代码
2009/03/17 PHP
基于Zend的Config机制的应用分析
2013/05/02 PHP
thinkphp在模型中自动完成session赋值示例代码
2014/09/09 PHP
PHP实现支付宝即时到账功能
2016/12/21 PHP
php框架CodeIgniter主从数据库配置方法分析
2018/05/25 PHP
PHP5.5新特性之yield理解与用法实例分析
2019/01/11 PHP
YII框架行为behaviors用法示例
2019/04/26 PHP
laravel中数据显示方法(默认值和下拉option默认选中)
2019/10/11 PHP
laravel 解决后端无法获取到前端Post过来的值问题
2019/10/22 PHP
laravel开发环境homestead搭建过程详解
2020/07/03 PHP
javascript-TreeView父子联动效果保持节点状态一致
2007/08/12 Javascript
js 编写规范
2010/03/03 Javascript
模拟jQuery ajax服务器端与客户端通信的代码
2011/03/28 Javascript
javascript 在firebug调试时用console.log的方法
2012/05/10 Javascript
JavaScript截取字符串的2个函数介绍
2014/08/27 Javascript
浅谈React 属性和状态的一些总结
2016/11/21 Javascript
Javascript中构造函数要注意的一些坑
2017/01/23 Javascript
js图片延迟加载(Lazyload)三种实现方式
2017/03/01 Javascript
JavaScript条件判断_动力节点Java学院整理
2017/06/26 Javascript
jQuery-ui插件sortable实现自由拖动排序
2018/12/01 jQuery
python文件与目录操作实例详解
2016/02/22 Python
python 添加用户设置密码并发邮件给root用户
2016/07/25 Python
python递归函数绘制分形树的方法
2018/06/22 Python
HTML5 canvas 瀑布流文字效果的示例代码
2018/01/31 HTML / CSS
德国机场停车位比较和预订网站:Ich-parke-billiger
2018/01/08 全球购物
Room Mate Hotels美国:西班牙酒店品牌
2018/04/10 全球购物
英国健身超市:Fitness Superstore
2019/06/17 全球购物
2014年单位植树节活动方案
2014/03/23 职场文书
委托公证书范本
2014/04/03 职场文书
第一批党的群众路线教育实践活动总结报告
2014/07/03 职场文书
最美护士演讲稿
2014/08/27 职场文书
父亲节活动总结
2015/02/12 职场文书
幼儿园教师教育随笔
2015/08/14 职场文书
学校学习型党组织建设心得体会
2019/06/21 职场文书
使用ORM新增数据在Mysql中的操作步骤
2021/07/26 MySQL
IDEA 2022 Translation 未知错误 翻译文档失败
2022/04/24 Java/Android