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

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

游戏功能:

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

1、html相关代码



 

 
 
 扫雷
 
 


 

 

剩余雷数:

TIME: S

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 += '
    '; //生成li for (var j = 0; j < map[0].length; j++) { var m = map[i][j] if (m == 0) { m = ""; } gridHTML += "
  • " + "" + m + "" + "" + "
  • " } gridHTML += '
' 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) }

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

你可能感兴趣的:(原生js实现自定义难度的扫雷游戏)