原生js實現自定義難度的掃雷游戲
更新時間:2021年01月22日 16:32:41 作者:清歡灬
這篇文章主要為大家詳細介紹了原生js實現自定義難度的掃雷游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了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.游戲的區(qū)域: 9*9的區(qū)域 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;
// 顯示所有地雷,獲取所有l(wèi)i
var all = document.querySelectorAll(".col");
// 放置所有的地雷
var ff = [];
var allnum = 0;
// 遍歷所有l(wèi)i
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();
// 獲取當前點擊節(jié)點
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)
}
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

