原生js實現自定義難度的掃雷遊戲
阿新 • • 發佈:2021-01-25
本文例項為大家分享了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,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,y - 1) plus(map,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,num) { //資料初始化 clearMineNum = 0 gg = false; //清除原來的地圖,生成新的地圖 var box = document.querySelector(".gameBox") box.innerHTML = ""; var map = mineMap(row,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,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,num) break; case "中級": row = 16; col = 16; num = 40; init(row,num) break; case "高階": row = 16; col = 30; num = 479; init(row,num) break; case "魔鬼級": row = 40; col = 50; num = 300; init(row,num) break; case "自定義": row = prompt("請輸入列數!"); col = prompt("請輸入行數!"); num = prompt("請輸入你想要的雷數,(請慎重選擇)"); init(row,num); break; default: row = 9; col = 9; num = 10; init(row,num) break; } } init(row,num) }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。