原生js实现自定义难度的扫雷游戏

本文实例为大家分享了js实现扫雷游戏的具体代码,供大家参考,具体内容如下

游戏功能:

1、有四个难度
2、可以自定难度

1、html相关代码

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>扫雷</title>
 <script src="js/mine.js"></script>
 <link rel="stylesheet" href="./css/mine.css" >
</head>
<!--
需求分析:
  1.游戏的区域:
   9*9的区域
  2.方格可以打开与标记
   左键打开,显示数字,为周围格子的地雷数,右键标记
  3.地雷
   地雷随机分布
  4.踩到地雷时,游戏结束
   所有的地雷显示出来
  5.连锁开大空方格
  6.剩余地雷数与计时器
  7.游戏胜利条件
   所有的方格除了地雷都被打开了,则游戏胜利
  一个方格所包含的信息:
   坐标 x y
   是否是一个地雷
   周围的地雷数 = 9
   二维数组中存储的是周围的地雷数
  -->

<body>
 <div class="level">
  <button type="button" name="button" class="choice-level">自定义</button>
  <button type="button" name="button" class="choice-level">初级</button>
  <button type="button" name="button" class="choice-level">中级</button>
  <button type="button" name="button" class="choice-level">高级</button>
  <button type="button" name="button" class="choice-level">魔鬼级</button>
  <button type="button" name="button" class="restart">重新开始</button>
 </div>
 <div class="gameBox"></div>
 <div class="info">
  <p>剩余雷数:
   <span class="residue"></span>
  </p>
  <p>
   TIME:
   <span class="tick"></span>S
  </p>

 </div>
</body>

</html>

2、css样式

*{
 margin: 0;
 padding: 0;
}
.gameBox{
 margin-top: 30px;
}
body{
 font-size: 0;
}
ul{
 list-style: none;
 text-align: center;
 overflow: hidden;
}
.col{
 display: inline-block;
 width: 22px;
 height: 22px;
 line-height: 22px;
 background-color: rgba(32, 226, 255, 0.4);
 border: 1px solid rgb(129, 129, 129);
 font-size: 16px;
 margin: 1.5px;
 vertical-align: top;
 position: relative;
}
.col:hover{
 background-color: #0af;
}
.col span{
 cursor: default;
}
.hide{
 display: none;
}
.boom{
 background: url("../img/boom.svg") no-repeat 2.5px 2px;
 background-size: 18px 18px;
}
.num-1{
 color: rgb(8, 153, 235);
}
.num-2{
 color: rgb(255, 45, 178);
}
.num-3{
 color:#16a085;
}
.num-4{
 color: #8e44ad;
}
.num-5{
 color: rgb(255, 167, 45);
}
.num-6{
 color: rgb(8, 126, 176);
}
.num-7{
 color: #e67e22;
}
.num-8{
 color: #c0392b;
}
.img-flag{
 width: 18px;
 height: 18px;
 position: absolute;
 top: 3px;
 left: 3px;
}
.level{
 margin-top: 30px;
 font-size: 20px;
 text-align: center;
}
.level button{
 padding: 5px 8px;
 background-color: rgb(67, 183, 189);
 border: none;
 outline: none;
 border-radius: 3px;
 cursor: pointer;
 color: #fff;
}
.level button:hover{
 background-color: rgb(23, 132, 138);
}
.info{
 margin-top: 30px;
 font-size: 16px;
 text-align: center;
}
.info p{
 display: inline-block;
 width: 130px;
 margin: 0 auto;
}
.info p span{
 color: rgb(67, 183, 189);
}

3、js代码

window.onload = function() {
 var row = 4;
 var col = 4;
 var num = 1;
 // 判断踩雷之后不能胜利
 var gg = false;
 // 生成地图
 function mineMap(r, c, num) {
  // 定义行
  var map = [];
  //给行数,生成二维数组
  for (var i = 0; i < r; i++) {
   map[i] = new Array()
  }
  // 赋值
  for (var i = 0; i < map.length; i++) {
   for (var j = 0; j < c; j++) {
    // //周围的地雷数
    map[i][j] = 0;
   }
  }
  var plus = function(array, x, y) {
   if (x >= 0 && x < r && y >= 0 && y < c) {
    if (array[x][y] !== 9) {
     array[x][y]++
    }
   }
  }
  for (var i = 0; i < num; i++) {
   var x = Math.floor(Math.random() * r)
   var y = Math.floor(Math.random() * c)
   if (map[x][y] != 9) {
    map[x][y] = 9
     //上下6个 +1
    for (var j = -1; j < 2; j++) {
     //上三个
     plus(map, x - 1, y + j)
      //下三个
     plus(map, x + 1, y + j)
    }
    //左右2个 +1
    plus(map, x, y - 1)
    plus(map, x, y + 1)
   } else {
    //重新随机
    num++
   }
  }
  return map;
 }
 //先通过x轴数量写入ul,再讲过y轴的属性写入li
 function writeHtml(map) {
  // 获取盒子
  var gameBox = document.querySelector(".gameBox");
  // 声明空字符串,存放生成的ul、li
  var gridHTML = "";
  for (var i = 0; i < map.length; i++) {
   gridHTML += '<ul class = "row" data-x="' + i + '">';
   //生成li
   for (var j = 0; j < map[0].length; j++) {
    var m = map[i][j]
    if (m == 0) {
     m = "";
    }
    gridHTML += "<li class='col' data-y=" + j + ">" +
     "<span class='hide num-" + m + "'>" + m + "</span>" +
     "<img src='img/flag.svg' class='img-flag hide'>" +
     "</li>"
   }
   gridHTML += '</ul>'
   gameBox.innerHTML = gridHTML;
  }
 }

 //给方格绑定事件, 点开数字 地雷 右键标记
 function show() {
  // 获取行ul
  var rows = document.querySelectorAll(".row");
  // 遍历所有ul
  for (var i = 0; i < rows.length; i++) {
   var element = rows[i];
   // 添加点击事件
   element.onclick = function(event) {
     // 当前点击元素
     var el = event.target;
     // 判断是否为li
     if (el.nodeName != "LI") {
      return;
     }
     //todo 判断是否被打开以及标记了
     if (el.style.background == "white" || !el.children[1].classList.contains("hide")) {
      return;
     }
     // 获取span标签内容
     var mineNum = el.children[0].innerHTML;
     if (mineNum !== "9" && el.style.background !== "white") {
      // 空白连锁打开
      if (mineNum == "") {
       var x = parseInt(el.parentNode.dataset.x);
       var y = parseInt(el.dataset.y);
       showNoMine(x, y);
      }
      // li背景变白色;span显示
      el.style.background = "white";
      el.children[0].style.display = "inline";
      // 判断打开数量
      clearMineNum++;
      // 胜利函数
      judgeVictory()

     } else if (mineNum == "9") {
      // 清除胜利计时器
      clearInterval(stopTime);
      // li添加类名
      el.classList.add("boom");
      alert("你真菜!")
      gg = true;
      // 显示所有地雷,获取所有li
      var all = document.querySelectorAll(".col");
      // 放置所有的地雷
      var ff = [];
      var allnum = 0;
      // 遍历所有li
      for (var i = 0; i < all.length; i++) {
       if (all[i].children[0].innerHTML == "9") {
        // 雷赋值给数组
        ff[allnum] = all[i];
        allnum++;
       }
      }
      // 设置一个计时器一个一个打开雷
      allnum = 0;
      var stop = setInterval(function() {
       ff[allnum].classList.add("boom")
       allnum++;
       // 判断结束条件
       if (allnum == ff.length) {
        // 清除计时器
        clearInterval(stop);
       }
      }, 30)

     }
    }
    // 右键标记地雷
   element.oncontextmenu = function(event) {
    // 阻止右键菜单
    event.preventDefault();
    // 获取当前点击节点
    var el = event.target;
    // 判断是否是
    if (el.parentNode.nodeName == "LI") {
     el = el.parentNode;
    }
    if (el.nodeName != "LI") {
     return;
    }
    // 获取img
    var classList = el.children[1].classList;
    // 剩余雷数
    var residue = document.querySelector(".residue");
    var mineNum = parseInt(residue.innerHTML);
    // 如果没有旗子,没有被点开,可以插旗子
    if (classList.contains("hide") && el.style.background != "white") {
     // 移除隐藏
     classList.remove("hide");
     // 获取雷数
     mineNum--;
    } else if (el.style.background != "white") {
     classList.add("hide");
     // 判断雷数
     if (mineNum < num) {
      mineNum++;
     }
    }
    // 剩余雷数
    residue.innerHTML = mineNum;
   }
  }
 }

 function judgeVictory() {
  //游戏胜利
  if (clearMineNum === (row * col - num)) {
   //做一个小动画
   var all = document.querySelectorAll(".col");
   var allNum = 0;
   var stop = setInterval(function() {
    var r = Math.floor(Math.random() * 256)
    var g = Math.floor(Math.random() * 256)
    var b = Math.floor(Math.random() * 256)
    all[allNum].style.background = "rgba(" + r + "," + g + "," + b + ",0.6)";
    //将旗子和span都隐藏
    all[allNum].children[0].style.display = "none"
    all[allNum].children[1].style.display = "none"
    allNum++
    if (allNum === all.length) {
     clearInterval(stop)
     if (!gg) {
      alert("大吉大利,今晚吃鸡")
      init(row, col, num)
     }
    }
   }, 20)
  }
 }
 //自动打开空格
 function showNoMine(x, y) {
  for (var i = -1; i <= 1; i++) {
   if (x + i >= 0 && x + i < row) {
    // 获取当前行
    var rowElement = document.querySelectorAll(".row")[x + i];
    for (var j = -1; j <= 1; j++) {
     if (y + j >= 0 && y + j < col) {
      //获取当前单元格
      var el = rowElement.children[y + j]
       //自动打开必须是未打开的方格
      if (el.style.background != "white") {
       el.style.background = "white"
       el.children[0].style.display = "inline"
        //打开方格数量+1
       clearMineNum++
       //判断游戏是否胜利
       judgeVictory(clearMineNum)

       if (el.children[0].innerText === "") {
        showNoMine(x + i, y + j)
       }
      }
     }
    }
   }
   // if (x + i >= 0 && x + i < row) {
   //  // 获取当前行
   //  var rowElement = document.querySelectorAll(".row")[x + i];
   //  for (var j = -1; j <= 1; j++ && y + j < col) {
   //   // 获取当前单元格
   //   var el = rowElement.children[y + j];
   //   if (el.style.background !== "white") {
   //    el.style.background = "white";
   //    el.children[0].style.display = "inline";
   //    // 打开放格数量加1
   //    clearMineNum++;
   //    // 判断游戏是否胜利
   //    judgeVictory(clearMineNum);
   //    // 判断打开周围的放格周围是否为空
   //    if (el.children[0].innerHTML === "") {
   //     showNoMine(x + i, y + j)
   //    }
   //   }
   //  }
   // }
  }

 }
 //初始化方法
 var stopTime;

 function init(row, col, num) {
  //数据初始化
  clearMineNum = 0
  gg = false;
  //清除原来的地图,生成新的地图
  var box = document.querySelector(".gameBox")
  box.innerHTML = "";
  var map = mineMap(row, col, num);
  // 新建地图
  writeHtml(map);
  show()
   //将雷数写入html中
  var residue = document.querySelector(".residue")
  residue.innerHTML = num
   // 获取计时
  var tick = document.querySelector(".tick");
  var i = 0;
  // 初始化
  tick.innerHTML = i;
  // 清除计时
  clearInterval(stopTime);
  // 时间计时器
  stopTime = setInterval(function() {
   tick.innerHTML = ++i
  }, 1000)
 }
 // 重置
 var restart = document.querySelector(".restart");
 restart.onclick = function(event) {
   //阻止冒泡
   event.stopPropagation()
   init(row, col, num)
  }
  // 自定义
 var level = document.querySelector(".level")
 level.onclick = function(event) {
  var el = event.target;
  switch (el.innerHTML) {
   case "初级":
    row = 9;
    col = 9;
    num = 10;
    init(row, col, num)
    break;
   case "中级":
    row = 16;
    col = 16;
    num = 40;
    init(row, col, num)
    break;
   case "高级":
    row = 16;
    col = 30;
    num = 479;
    init(row, col, num)
    break;
   case "魔鬼级":
    row = 40;
    col = 50;
    num = 300;
    init(row, col, num)
    break;
   case "自定义":
    row = prompt("请输入列数!");
    col = prompt("请输入行数!");
    num = prompt("请输入你想要的雷数,(请慎重选择)");
    init(row, col, num);
    break;
   default:
    row = 9;
    col = 9;
    num = 10;
    init(row, col, num)
    break;
  }
 }
 init(row, col, num)
}

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

时间: 2021-01-20

JavaScript版经典游戏之扫雷游戏完整示例【附demo源码下载】

本文实例讲述了JavaScript扫雷游戏.分享给大家供大家参考,具体如下: 翻出年初写的游戏贴上来,扫雷相信大家都玩过,先上图: 源码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.or

js实现简单扫雷

本文实例为大家分享了js实现简单扫雷的具体代码,供大家参考,具体内容如下 实现效果: 总体思想:这个扫雷难点主要就两点:第一点就是雷的随机分布,我这里使用js动态生成了10X10的table表格,然后设定生成20个雷,然后在生成每个格子代表的数字,雷我们用9表示,因为0-8要被其他非雷格子使用,然后我们只要一格是雷区那么周围的格子都加一,这样我们的雷区就生成好了,然后玩法的编写主要难点就是在当点击数字为0时的格子时要把它周围的0区也显示出来,因此这里我们使用递归来实现 1.界面的生成 //生成界

分享自己用JS做的扫雷小游戏

引用了jQuery,节省了很多鼠标点击上的判断.界面显然都是照搬Windows的扫雷啦,详细的内容注释里都有,我就不啰嗦啦~ 先上截图~ 引用了jQuery,节省了很多鼠标点击上的判断 界面显然都是照搬Windows的扫雷啦 详细的内容注释里都有,我就不啰嗦啦~ JS部分 var mineArray, //地雷数组 lastNum, //剩余雷数 countNum, //未被揭开的方块数 inGame = 0, //游戏状态,0为结束,1为进行中,2为初始化完毕但未开始 startTime; /

js+canvas实现简单扫雷小游戏

扫雷小游戏作为windows自带的一个小游戏,受到很多人的喜爱,今天我们就来尝试使用h5的canvas结合js来实现这个小游戏. 要写游戏,首先要明确游戏的规则,扫雷游戏是一个用鼠标操作的游戏,通过点击方块,根据方块的数字推算雷的位置,标记出所有的雷,打开所有的方块,即游戏成功,若点错雷的位置或标记雷错误,则游戏失败. 具体的游戏操作如下 1.可以通过鼠标左键打开隐藏的方块,打开后若不是雷,则会向四个方向扩展 2.可以通过鼠标右键点击未打开的方块来标记雷,第二次点击取消标记 3.可以通过鼠标右键

JavaScript制作windows经典扫雷小游戏

代码其实很简单,这里就不多废话了 <html> <head> <meta http-equiv="Content-Language" content="zh-cn"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>扫雷-JavaScript Mine Sweeper

使用纯javascript实现经典扫雷游戏

很久以前写的 当时都没写注释的 刚加上了 (尼玛,好多自己都不认识了 ... ) 不足的地方就是本来想写个游戏排名的统计的,等有空了再加上(好像每次都这么说 然后就等好久好久...) 还有就是没有实现:点击第一个格子不能是雷的功能 <style> ul{padding:0;list-style:none;} #mine{overflow:hidden;width:30px;height:30px;border:1px solid #966;} #mine li{float:left;width

javascript 扫雷游戏

"); for (var i = 0; i "); for(var j = 0; j   "); buffer.append(" "); } buffer.append(" "); var workarea = document.getElementById("workarea"); workarea.innerHTML = buffer.toString(); mine(); // lay mines at the

HTML+JavaScript实现扫雷小游戏

本文实例为大家分享了JavaScript实现扫雷小游戏的具体代码,供大家参考,具体内容如下 工具:Sublime Text / Dreamweaver /Hbuilder <!doctype html> <html> <head> <meta charset="utf-8"> <title>SaoLei</title> <style type="text/css"> table {

js版扫雷实现代码 原理不错

效果图:以下代码复制粘贴到记事本后保存为.html文件,打开后会出现提示,右击允许即可: 寻雷-----by 魅月 var data=new Array( [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0

js实现扫雷小程序的示例代码

初学javascript,写了一个扫雷程序练练手! 扫雷规则及功能 扫雷想必大家都不陌生,就是windows上点击排雷的小游戏,它的主要规则有 1.左键点击显示当前格子是否为雷,如果为雷的话,GameOver啦,如果不是雷的话,这个格子会显示周围八个格子内的雷数量. 2.鼠标右键标记,标记可能的雷,标记了之后取消需要再次右键点击该格子,左键无效果. 3.鼠标中键(滚轮)按下后,快捷扫雷(如果周围雷数和未被标记且未被翻开的格子相等,会将这些格子一并翻开) 主要功能基本完全复刻了windows7扫雷

京东优选小程序的实现代码示例

写在前面 过年有大把的时光,为何一直宅在家里不出家门看着电脑,这究竟是道德的沦丧还是人性的泯灭...这一切都还得从一只蝙蝠说起... 咳咳,好了不皮了,言归正传.微信推出的小程序可谓是轻量又强大,所以最近我也开始了小程序的学习,学了挺多也看了很多文档,但总觉得自己没学到什么,感觉很迷茫.正所谓实践出真知,所以我选择了从高仿别人的小程序开始,选来选去最后选择了京东优选这个小程序(绝对不是因为它的界面清爽!). 开发工具 微信开发者工具 VS Code 效果速览 废话不多说,咱先来搞一波图片看看,点

使用Vue.js开发微信小程序开源框架mpvue解析

前言 mpvue是一款使用Vue.js开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为H5和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程序,或开发小程序后希望将其转换为H5,mpvue将是十分契合的一种解决方案. 目前,mpvue已经在美团点评多个实际业务项目中得到了验证,因此我们决定将其开源,希望更多技术同行一起开发,应用到更广泛的场景里去.github项目地址请参见mpvue .使用文档请参见 http://mpvue.com/. 为了帮

微信小程序日历插件代码实例

这篇文章主要介绍了微信小程序日历插件代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.wxml代码 <view class="timePick"> <picker mode="date" fields="month" value="{{timestamp}}" start="1999-01-01" end="2999-

JS绘制微信小程序画布时钟

微信小程序官方组件也提供了画布功能,下面分享一下如何创建微信小程序画布时钟. 总体思路是对pages中的一个小程序页面构建画布时钟逻辑程序,通过app.json公共设置来配置入口. 首先来看一下构建这样一个小程序所需要的目录结构 从目录结构就可以看出来这个程序是简单的单层页面,画布渲染在pages下面的index页面上. 其中对程序有实际驱动作用的代码分别在index.js,index.wxml,index.wxss和app.json这几个文件中 Index.js文件里面存放着程序的逻辑层数据,

JS中微信小程序自定义底部弹出框

实现微信小程序底部弹出框效果,代码分为html,css和js两部分,具体代码详情大家参考下本文. html <view class="commodity_screen" bindtap="hideModal" wx:if="{{showModalStatus}}"></view> <view animation="{{animationData}}" class="commodity_a

利用js实现前后台传送Json的示例代码

无论使用什么框架都存在着从controller向Html页面或者jsp页面传递数据的问题,最常用的方式是传递Json字符串.以前对这块知识有些模糊,现在整理一下. [Jquery基本方法] 实现传值常用的是Jquery以及内部封装的ajax.首先看一下jquery的get()和post()语法.get()方法是从服务器获得数据,其主要参数就是获得后台请求地址,以及负责处理的回调函数: $.get(URL,callback); $("button").click(function(){

django js实现部分页面刷新的示例代码

例子中,我用的是显示机器上的进程信息的表格,获取不同的机器的进程信息时,更新这个展示信息的表格,如下: 当我在输入框中输入ip时,我希望只是更新这个表格,页面其他部分不变,实现方式如下: 1.在原页面中设置这个表格的id为pstable <table class="table table-striped" id="pstable"> <thead> <tr> <th>user</th> <th>

使用node.js实现微信小程序实时聊天功能

在微信这个聊天工具里的小程序上实现聊天功能,总感觉怪怪的.但领导要求了,总是要干的. 然后就实时通讯这个关键词展开搜索,穿梭于网页之间.不过粘贴复制的真的太多了,找了半天也没找到想要的,不过还是提取到了关键词的WebSocket和node.js的,然后搜索这两是啥,什么关系,总算明白了一点. 最后确定了第一步需要干的是用node.js搭建服务(我是装在自己的windows下的): 1.首先到官网下载node.js,下载链接 安装很简单,双击下载好的文件,直接下一步一步,没什么特殊的选择,路径默认

node.js 用socket实现聊天的示例代码

本文介绍了node.js 用socket实现聊天的示例代码,分享给大家,也给自己留个笔记,具体如下: 服务器搭建 app.js const http = require("http"); const express = require("./express"); //创建一个服务 const server = http.createServer(express); //监听服务端口 server.listen(8001,()=>{ console.log(&q