本文实例为大家分享了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)
}

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

原生js实现自定义难度的扫雷游戏的更多相关文章

  1. html5 拖拽及用 js 实现拖拽功能的示例代码

    这篇文章主要介绍了html5 拖拽及用 js 实现拖拽,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. amaze ui 的使用详细教程

    这篇文章主要介绍了amaze ui 的使用详细教程,本文通过多种方法给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. swift皮筋弹动发射飞机ios源码

    这是一个款采用swift实现的皮筋弹动发射飞机游戏源码,游戏源码比较详细,大家可以研究学习一下吧。

  4. Swift与Js通过WebView交互

    开发环境:Swfit2.3XCode8.2基础概念jscontext,jscontext是代表JS的执行环境,通过-evaluateScript:方法就可以执行一JS代码JSValue,JSValue封装了JS与ObjC中的对应的类型,以及调用JS的API等JSExport,JSExport是一个协议,遵守此协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来,才能调用Swif

  5. JSCore swift

    如果双方相互引用,会造成循环引用,而导致内存泄露。以上是Jscore的基本使用,比较简单

  6. Swift WKWebView的js调用swift

    最近项目需求,需要用到JavaScriptCore和WebKit,但是网上的资源有限,而且比较杂,都是一个博客复制另外一个博客,都没有去实际敲代码验证,下面给大家分享一下我的学习过程。

  7. Swift WKWebView的swift调用js

    不多说,直接上代码:在html里面要添加的的代码,显示swift传过去的参数:这样就实现了swift给js传参数和调用!

  8. 在 Swift 專案中使用 Javascript:編寫一個將 Markdown 轉為 HTML 的編輯器

    你有強烈的好奇心,希望在你的iOS專案中使用JavaScript。jscontext中的所有值都是JSValue對象,JSValue類用於表示任意類型的JavaScript值。因此,我們既需要寫Swift代碼也要寫JavaScript代碼。此外,我們還會在JavaScript中按照這個類的定義來創建一個對象并對其屬性進行賦值。從Swift中呼叫JavaScript就如介紹中所言,JavaScriptCore中最主要的角色就是jscontext類。一個jscontext對象是位於JavaScript環境和本

  9. swift - WKWebView JS 交互

    本文介绍WKWebView怎么与js交互,至于怎么用WKWebView这里就不介绍了HTML代码APP调JS代码结果JS给APP传参数首先注册你需要监听的js方法名2.继承WKScriptMessageHandler并重写userContentController方法,在该方法里接收JS传来的参数3.结果

  10. swift 开发UIWebView跟JS的交互

    前言作为小白的我,才开始入门IOS,选择了swift来进行入门学习,学习做着公司一个简单的小小项目,该项目需要进行跟H5进行交互,然后我就开始研究了UIWebView的使用,其实基本原理跟Android的一样,因为我是Android开发的,所以就顺水推舟了。))//这里设置你需要加载的地址}overridefuncdidReceiveMemoryWarning(){super.didReceiveMemoryWarning()//disposeofanyresourcesthatcanberecreate

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部