使用JavaScript怎么编写一个自定义难度的扫雷游戏
创始人
2024-12-29 04:42:02
0次

游戏功能:

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)
}

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...