用js来做扫雷效果

用js来做扫雷效果

来喽来喽,带着代码奔过来喽

js部分


// 标记的旗子数量
var flagNum = 10;
// 点击按钮可以生成不同的难度。 初级:9*9 中级16*16 高级:16*30
var gameBox = document.querySelector(".gameBox");

function createHTML(row,col,num) {
  var map = new Array();
  for (var i = 0; i < row; i++) {
    var item = new Array();
    for (var j = 0; j < col; j++) {
      item[j] = 0;
    }
    map[i] = item;
  }
  for (var k = 0; k < num; k++) {
    // 地雷的行
    var x = parseInt(Math.random() * row);
    // 地雷的列
    var y = parseInt(Math.random() * col);
    if (map[x][y] == 9) {
      k--;
      continue;
    }
    // 假设数字9表示地雷
    map[x][y] = 9;
    // 让上面三个格子,下面三个格子,左右两个格子的数字+1
    // x y 为坐标,array为数组
    var plus = function(array,x,y){
      if (x>=0&&y>=0&&x<row&&y<col) {
        if (array[x][y]!=9) {
          array[x][y]++;
        }
      }
    }
    // 上面三个格子的数量+1
    for(var h = -1;h < 2;h++){
      plus(map,x-1,y+h);
    }
    // 下面三个格子的数量+1
    for(var m = -1;m < 2;m++){
     plus(map,x+1,y+m)
    }
    // 左右两边的数量+1
    plus(map,x,y-1);
    plus(map,x,y+1)
  }
 
  var str = "";
  for (var i = 0; i < map.length; i++) {
    str += "<ul data-row="+i+">"
    for (var j = 0; j < map[i].length; j++) {
      if (map[i][j] == 0) {
        map[i][j] = "";
      }
      str += "<li data-col="+j+">" +
        "<span class='hide num-" + map[i][j] + "'>" + map[i][j] + "</span>" +
        "<img src='img/flag.svg' class='img-flag hide'>"+
        "</li>";
    }
    str += "</ul>";
  }
  gameBox.innerHTML = str;
}
var level = document.getElementsByClassName("level")[0];
// 记录难度的等级: 0 初级 1中级 2高级
var levelNum = 0;
level.onclick = function (ev) {
  var target = ev.target;
  switch (target.innerHTML) {
    case "初级":
      createHTML(9, 9,10);
      levelNum = 0;
      break;
    case "中级":
      createHTML(16, 16,20)
      levelNum = 1;
      break;
    case "高级":
      createHTML(16, 30,30);
      levelNum = 2;
      break;
    case "重新开始":
      switch (levelNum) {
        case 0:
          createHTML(9, 9,10);
          break;
        case 1:
          createHTML(16, 16,20);
          break;
        case 2:
          createHTML(16, 30,30);
          break;
      }
      break;
  }
}
// 初始化方法
function init() {
  // 第一个9表示二维数组中有9个元素,每个元素都是一个数组,每个数组又包含9个元素。
  createHTML(9,9,10);
}

// 小格子的点击事件
function show(){
  // 左键点击事件
  gameBox.onclick = function(ev){
    var target = ev.target;
    if(target.nodeName != "LI"){
      return;
    }
    // 如果是已经翻开了,或者标记了,不应该做操作。
    if (target.style.backgroundColor == "white" || !target.children[1].classList.contains("hide")) {
      return;
    }
    // 判断点击的是不是地雷。 mine为9表示地雷。
    var mine = target.firstChild.innerHTML;
    if (mine != "9") {
      // 雷数如果为空,说明这个格子周围没有一颗雷。应该自动打开。
      if (mine == "") {
        // 获取当前格子的横坐标
        var x = parseInt(target.parentNode.dataset.row);
      // 获取当前格子的纵坐标
        var y = parseInt(target.dataset.col);
        showNoMine(x,y);
      }
      target.style.backgroundColor = "white";
      target.firstChild.classList.remove("hide");
    }else{
      // 游戏结束
      alert("这都不会算?去玩连连看吧");
      // 让所有的地雷显示出来。
      var all = document.querySelectorAll(".num-9");
      for (var i = 0; i < all.length; i++) {
        all[i].classList.remove("hide");
        all[i].classList.add("boom");
        all[i].innerHTML = "";
      }
    }
  }

  gameBox.oncontextmenu = function(ev){
    // 阻止浏览器的默认行为
    ev.preventDefault();
    var el = ev.target;
   
    if (el.parentNode.nodeName == "LI") {
      el = el.parentNode;
    }
    if (el.nodeName != "LI") {
      return;
    }
    
    // 如果没有插旗子,也没有被点开,则可以标记
    if (el.style.backgroundColor!="white"&&el.children[1].classList.contains("hide")&&flagNum>0) {
      el.children[1].classList.remove("hide");
      // 剩余雷数-1;
      flagNum--;
    }else if(!el.children[1].classList.contains("hide")){
      // 剩余雷数+1;
      flagNum++;
    }
    judgeVictory();
  }

}
// 判断游戏是否胜利
function judgeVictory(){
  // 所有的雷上面都插上了旗子,说明游戏胜利。
  var mine = document.querySelectorAll(".num-9");
  // 假设所有的雷都插上了旗子。
  var flag = true;
  for (var i = 0; i < mine.length; i++) {
    if(mine[i].nextElementSibling.classList.contains("hide")){
      flag = false;
      break;
    }
  }
  if (flag) {
    alert("游戏胜利!")
  }
}
// 当前格子的横纵坐标。
function showNoMine(x,y){
  var ul = document.querySelectorAll("ul");
  var open = function(x,y){
    if (x>=0&&x<ul.length) {
      // 执行打开操作。
      var lis = ul[x].getElementsByTagName("li");
      if (y>=0&&y<lis.length) {
        var el = lis[y];
        // 自动打开必须是未打开的方格。
        if (el.style.backgroundColor != "white") {
          el.style.backgroundColor = "white";
          el.firstChild.classList.remove("hide");
          // 如果打开的方格又是一个空白,则继续打开。
          if (el.firstElementChild.innerHTML == "") {
            showNoMine(x,y)
          }
        }
       
      }
    }
  }
  // 上面三个格子打开
  for(var h = -1;h < 2;h++){
    open(x-1,y+h);
  }
  // 下面三个格子的数量+1
  for(var m = -1;m < 2;m++){
    open(x+1,y+m)
  }
  // 左右两边的数量+1
  open(x,y-1);
  open(x,y+1)
}
init();
show();

html部分

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="css/mine.css">
</head>
<body>
  <!-- 
    1.先完成静态页面。
   -->
   <!-- 等级选择模块 -->
   <div class="level">
     <button class="btn">初级</button>
     <button class="btn">中级</button>
     <button class="btn">高级</button>
     <button class="btn">重新开始</button>
   </div>
   <div class="gameBox">
    
   </div>
   <!-- 地雷游戏信息:雷数和时间 -->
   <div class="info">
     <p>剩余雷数:
       <span class="residue">10</span>
     </p>
     <p>时间:
       <span class="time">10</span>
     </p>
   </div>
  <script src="js/mine6.0.js"></script>
</body>
</html>

css部分

*{
  margin: 0;
  padding: 0;
}
ul{
  list-style: none;
  text-align: center;
}
li{
  width: 22px;
  height: 22px;
  display: inline-block;
  line-height: 22px;
  background-color: rgba(32, 226, 255, 0.4);
  border: 1px solid rgb(129, 129, 129);
  margin: 1px;
  vertical-align: top;
  position: relative;
}
.level{
  margin: 30px;
  text-align: center;
}
.info{
  text-align: center;
  margin-top: 20px;
}
.info p{
  display: inline-block;
  width: 130px;
  margin: 0 auto;
}
.level button{
  background-color: rgb(67, 183, 189);
  padding: 5px 8px;
  border: none;
  border-radius: 3px;
  color: #fff;
  cursor: pointer;
}
.level button:hover{
  background-color: rgb(23, 132, 138);
}
.img-flag{
  width: 18px;
  height: 18px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%,-50%);

}
.hide{
  display: none;
}
.num-1{
  color: #2ecc71;
}
.num-2{
  color: #f1c40f;
}
.num-3{
  color:#e74c3c;
}
.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;
}
.boom{
  background-image: url("../img/boom.svg");
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}
li span{
  width: 100%;
  height: 100%;
  display: inline-block;
}

在这里插入图片描述
在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值