JS扫雷小游戏
HTML代码
<title>
  扫雷
</title>
<!-- ondragstart:防拖拽生成新页面 oncontextmenu:屏蔽右键菜单-->
<body ondragstart='return false' oncontextmenu='self.event.returnValue=false'>
  <div id='bar'>
    <span class='bar'>
      剩余雷数:
      <label id='count'>
        0
      </label>
    </span>
    <span class='bar'>
      计时:
      <label id='time'>
        0
      </label>
      s
    </span>
  </div>
  <table id='grid'>
  </table>
CSS代码
#bar {
      text-align: center;
      margin-bottom: 20px;
    }
    .bar {
      height: 25px;
      width: 150px;
      line-height: 25px;
      display: inline-block;
      border: solid 1px #000;
      margin-left: 20px;
      margin-right: 20px;
    }
    #grid {
      margin: auto;
    }
    .blocks {
      width: 30px;
      height: 30px;
      line-height: 30px;
      display: block;
      text-align: center;
      border: solid 1px #000;
      user-select: none;
      cursor: pointer;
    }
    .blocks:hover {
      background: #0af;
    }
JS代码
var row = 10; //行数
var col = 10; //列数
var maxCount = 10; //最大地雷数量
var isFirstOpen = true; //第一次打开方格
var grid = init_grid(); //初始化
var count = document.getElementById('count'); //剩余地雷数
count.innerHTML = maxCount; //初始化剩余雷数
var time = document.getElementById('time'); //计时器
var timer = setInterval(function() {
  let seconds = (parseFloat(time.innerHTML) + 0.1).toFixed(1); //保留一位小数
  time.innerHTML = seconds;
},
100) //定时器 100ms执行一次
//初始化矩阵 (row-行数 col-列数)
function init_grid() {
  //生成矩阵html <tr>--行标签 <td>--列标签
  let gridHtml = '';
  for (let i = 0; i < row; i++) {
    gridHtml += '<tr>'
    for (let j = 0; j < col; j++) {
      gridHtml += '<td><span class="blocks" onmousedown="block_click(' + i + ',' + j + ',event)"></span></td>';
    }
    gridHtml += '<tr>'
  }
  //写入html
  document.getElementById('grid').innerHTML = gridHtml;
  //返回矩阵二维数组
  let blocks = document.getElementsByClassName('blocks');
  let grid = new Array();
  for (let i = 0; i < blocks.length; i++) {
    if (i % col === 0) {
      grid.push(new Array());
    }
    //初始化计雷数
    blocks[i].count = 0;
    grid[parseInt(i / col)].push(blocks[i]);
  }
  return grid;
}
//方格点击事件 _i:坐标i _j:坐标j e:鼠标事件
function block_click(_i, _j, e) {
  //跳过已打开的方格
  if (grid[_i][_j].isOpen) {
    return;
  }
  //鼠标左键打开方格
  if (e.button === 0) {
    //第一次打开
    if (isFirstOpen) {
      isFirstOpen = false;
      let count = 0; //当前地雷数
      //生成地雷
      while (count < maxCount) {
        //生成随机坐标
        let ri = Math.floor(Math.random() * row);
        let rj = Math.floor(Math.random() * col);
        //坐标不等于第一次点击方格的坐标 && 非雷方格
        if (! (ri === _i && rj === _j) && !grid[ri][rj].isMine) {
          grid[ri][rj].isMine = true; //自定义属性isMine代表方格为地雷
          count++; //当前地雷数+1
          //更新九宫格内非雷方格的计雷数
          for (let i = ri - 1; i < ri + 2; i++) {
            for (let j = rj - 1; j < rj + 2; j++) {
              //判断坐标防越界
              if (i > -1 && j > -1 && i < row && j < col) {
                //计雷数+1
                grid[i][j].count++;
              }
            }
          }
        }
      }
    }
    //执行打开方格函数
    block_open(_i, _j);
    //打开方格函数
    function block_open(_i, _j) {
      let block = grid[_i][_j];
      op(block);
      //设定打开方格的状态与样式
      function op(block) {
        block.isOpen = true; //isOpen为自定义属性,设置为true代表已打开
        block.style.background = '#ccc'; //将背景设置为灰色
        block.style.cursor = 'default'; //将鼠标停留样式设置为默认
      }
      if (block.isMine) {
        //踩雷
        block.innerHTML = '雷'; //显示为 '雷'
        //遍历矩阵打开所有的地雷方格
        for (let i = 0; i < row; i++) {
          for (let j = 0; j < col; j++) {
            //找到地雷
            block = grid[i][j];
            if (!block.isOpen && block.isMine) {
              op(block); //设置打开状态和样式
              block.innerHTML = '雷'; //显示为 '雷'
            }
          }
        }
        clearInterval(timer); //游戏结束停止计时,清除定时器
        //提示游戏结束
        alert("游戏结束");
      } else if (block.count === 0) {
        //打开计雷数为0的方格
        //遍历九宫格内的方格
        for (let i = _i - 1; i < _i + 2; i++) {
          for (let j = _j - 1; j < _j + 2; j++) {
            //判断是否越界&&跳过已打开的方格&&非雷
            if (i > -1 && j > -1 && i < row && j < col && !grid[i][j].isOpen && !grid[i][j].ismine) {
              //递归打开方格函数
              block_open(i, j);
            }
          }
        }
      } else {
        //打开计雷数不为0的方格
        block.innerHTML = block.count; //显示计雷数
      }
    }
  }
  //鼠标右键标记方格
  else if (e.button === 2) {
    let block = grid[_i][_j];
    if (block.innerHTML !== '▲') {
      block.innerHTML = '▲';
    } else {
      block.innerHTML = '';
    }
  }
  //遍历矩阵
  let isWin = true;
  count.innerHTML = maxCount; //重置剩余地雷数
  for (let i = 0; i < row; i++) {
    for (let j = 0; j < col; j++) {
      let block = grid[i][j];
      //找到标记
      if (block.innerHTML === '▲') {
        count.innerHTML = parseInt(count.innerHTML) - 1; //剩余地雷数-1
      }
      //判断游戏胜利条件(所有的非雷方格已打开)
      if (!block.isMine && !block.isOpen) {
        //如果有未打开的非雷方块 条件不成立
        isWin = false;
      }
    }
  }
  if (isWin) {
    clearInterval(timer); //游戏胜利结束计时,清除定时器
    alert("游戏胜利");
  }
}
JS扫雷小游戏的更多相关文章
- Angular4 扫雷小游戏
		扫雷小游戏,可以升级过关,难度随关卡增加.但是有很明显的bug,以后有时间会继续优化! HTML: <div class="mainContent"> <div ... 
- pixi.js 微信小游戏 入手
		pixi是什么?一款h5游戏引擎 优点:简单简洁性能第一 缺点:大多数用的国产三大引擎,pixi资料少,工具少, 为什么学,装逼 用pixi开发小游戏行吗? 行.但要简单处理下 下载官网上的 weap ... 
- 扫雷小游戏PyQt5开发【附源代码】
		也没啥可介绍哒,扫雷大家都玩过. 雷的分布算法也很简单,就是在雷地图(map:二维数组)中,随机放雷,然后这个雷的8个方位(上下左右.四个对角)的数字(非雷的标记.加一后不为雷的标记)都加一. 如何判 ... 
- JS写小游戏(一):游戏框架
		前言 前一阵发现一个不错的网站,都是一些用html5+css+js写的小游戏,于是打算学习一番,写下这个系列博客主要是为了加深理解,当然也有一些个人感悟,如果英文好可以直接Click Here. 概述 ... 
- web版扫雷小游戏(一)
		作为一名程序猿,平时的爱好也不多,说起游戏,我不太喜欢大型的网游,因为太耗时间,偶尔玩玩经典的单机小游戏,比如windows下自带的游戏扫雷(秀一下,高级下最高纪录110s). 现阶段正在致力于web ... 
- three.js 微信小游戏
		最近在 https://classroom.udacity.com/courses/cs291 学习了一些 3D 引擎和 three.js 的知识 把 three.js 弄到微信小游戏里,先随便跑一跑 ... 
- js消除小游戏(极简版)
		js小游戏极简版 (1) 基础布局 <div class = "box"> <p></p> <div class="div&qu ... 
- C++扫雷小游戏(基于CMD命令行)
		这个小游戏是笔者在大一C语言课程设计的时候写的,基于命令行,为了显得漂亮一些,特别加上了彩色特效~~~ 注意:Win10系统须将命令行调为旧版命令行,否则有可能会显示乱码! 代码示例: #includ ... 
- 无聊的周末用Java写个扫雷小游戏
		周末无聊,用Java写了一个扫雷程序,说起来,这个应该是在学校的时候,写会比较好玩,毕竟自己实现一个小游戏,还是比较好玩的.说实话,扫雷程序里面核心的东西,只有点击的时候,去触发更新数据这一步. Sw ... 
随机推荐
- 1.Solr安装与配置
			1.Solr安装 1:安装 Tomcat,解压缩即可. 2:解压 solr. 3:把 solr 下的dist目录solr-4.10.3.war部署到 Tomcat\webapps下(去掉版本号). 4 ... 
- [NOIP2016]换教室 题解(奇怪的三种状态)
			2558. [NOIP2016]换教室 [题目描述] 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有2n节课程安排在n个时间段上.在第i(1< ... 
- Jmeter自定义Java请求开发
			一.本次实验目的 IDEA新建maven项目,使用java开发自定义jmeter的请求. 本次开发使用的代码,会百度云分享给大家. 二.本次实验环境 Idea 2017.02 Jmeter 5.1.1 ... 
- Java线程安全与数据同步
			import java.util.HashMap; import java.util.concurrent.TimeUnit; public class Test { public static vo ... 
- UVA297 四分树 Quadtrees 题解
			题目链接: https://www.luogu.org/problemnew/show/UVA297 附几道推荐题目(先完成再食用此题效果更佳) https://www.luogu.org/probl ... 
- [USACO07FEB]银牛派对Silver Cow Party
			题目简叙: 寒假到了,N头牛都要去参加一场在编号为X(1≤X≤N)的牛的农场举行的派对(1≤N≤1000),农场之间有M(1≤M≤100000)条有向路,每条路长Ti(1≤Ti≤100). 每头牛参加 ... 
- 找到linux中当前java的安装位置
			先看java -version $java version "1.8.0_111" Java(TM) SE Runtime Environment (build 1.8.0_111 ... 
- 个人永久性免费-Excel催化剂功能第99波-手机号码归属地批量查询
			高潮过往趋于平静,送上简单的手机号码归属地查询,因接口有数量限制,仅能满足少量数据需求,如有大规模数据却又想免费获得,这就成为无解了,数据有价,且用且珍惜. 业务使用场景 除了日常自带的手机各种管家为 ... 
- Visual Studio 调试系列1 Debug 与 Release 模式
			系列目录 [已更新最新开发文章,点击查看详细] Debug 模式 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序. 在Debug模式下调试,可以在断点处看到 ... 
- JavaScript ES6 Promiss对象
			说明 Node.js中,以异步(Async)回调著称,使用了异步,提高了程序的执行效率,但是,代码可读性较差的. 假如有几个异步操作,后一个操作需要前一个操作的执行完毕之后返回的数据才能执行下去,如果 ... 
