Javascript 實作踩地雷小遊戲

Chen
5 min readJun 15, 2023

--

4月結束Alpha camp課程,接著開始求職準備作品集。在學期中有個作業是製作翻牌遊戲,當時就有想嘗試使用Javascript製作童年回憶「踩地雷遊戲」的想法。

雖然網路上可以找到許多使用Javascript製作的小遊戲,踩地雷遊戲可能也不大稀奇,但每個人在實作上的思考邏輯可能也不太相同,也想給自己個挑戰試試看能不能做出來。

思考的流程:

  1. 目標功能描述:
    (1) 製作一個10x10格的遊戲版面,總共有20個炸彈。
    (2) 玩家透過滑鼠左、右鍵,進行「踩」地雷&標記地雷,正確標記出所有地雷且其餘格子全數踩過即可獲勝。
    (3) 踩到地雷即遊戲結束。
    (4) 踩到的格子會顯示該格子附近「8」個位子的地雷數。

了解這個遊戲的玩法後,開始思考時做的步驟與想法拆解

2. 實作思考流程:
(1) 製作10x10的遊戲,裡面須包含20個地雷
(2) 滑鼠游標的點擊判斷邏輯。
(3) 顯示四周地雷數
(4) 「踩」地雷若四周2個位子都沒有地雷會散開直到碰到周圍有地雷的格子為止。
(5) 判斷遊戲是否結束

製作10x10的遊戲,裡面須包含20個地雷

這裡想要做的方式是,創立一個80個的"valid"元素的array,一個20個”bomb”的array, 兩者合起來後使用fisher-yates-shuffle進行打亂洗牌。

對洗好的array使用 forEach 將"valid"、"bomb"標記於data-attribute上,之後可以透過檢查這個資料判斷是否踩到地雷。

const table = document.querySelector(".table");

renderGameBoard(){
const arr = this.shuffleBoard();
let rawHTML = ``;
arr.forEach((item, i)=> {
rawHTML += `
<div class='cell' id=${i} data-symbol='${item}'></div>
`
})
table.innerHTML = rawHTML
},
shuffleBoard(){
const validArray = Array(tableCellCount - bombs).fill('valid');
const bombsArray = Array(bombs).fill('bomb');
const shuffleArray = validArray.concat(bombsArray);

for(let i = shuffleArray.length - 1; i > 0; i--){
let j = Math.floor(Math.random() * (i + 1));
[shuffleArray[i], shuffleArray[j]] = [shuffleArray[j], shuffleArray[i]];
}
return shuffleArray
},

滑鼠游標的點擊判斷邏輯

將每個格子加上事件監聽在近一步判斷始點擊左鍵還右鍵。
- 當點擊左鍵,判斷是否踩到地雷,若是則顯示地雷圖案;否則判斷周圍是否有地雷。
- 當點擊右鍵,加上旗子表示標記地雷。

handleClick(target, action){
if(action === 0){
//點擊右鍵
...
}else if (action === 2){
//點擊左鍵
...
}
}

document.querySelectorAll('.table').forEach(item => {
item.addEventListener('mouseup', e => {
const target = e.target;
const action = e.button;
utility.handleClick(target, action)
})
})

顯示四周地雷數

這個部分比較麻煩,要先定義好格子周圍的8個位置,在創立好的遊戲板子上forEach遍歷每個格子,並判斷是否有地雷(data-attribute),該地雷數的資訊紀錄在該node節點上(setAttribute(‘’))。

「踩」地雷若四周2個位子都沒有地雷會散開直到碰到周圍有地雷的格子為止。

要有這樣擴散出去的效果,可以想到是,當我點擊特定的格子時,同時也去觸發格子周圍8個位置的點擊事件,這樣就可以達到效果。
在點擊事件中判斷若地雷數為0,則觸發周圍的點擊,直到地雷數不為0的格子就停止這個循環。

判斷遊戲是否結束

重新回顧一下,什麼情況是贏了遊戲:
1. 當玩家正確把全部的地雷數標記起來
2. 剩餘的格子全數「踩過」

遊戲失敗的條件就只有: 踩到地雷。

第一個條件,想到的是,宣告一陣列把有地雷的格子id全部記錄起來,當點擊標記格子時,去記錄陣列找是否有該id;有的話把該id移除陣列,直到這個紀錄陣列為空陣列,就表示地雷已經全數正確標記起來了。

第二條件,宣告一變數記錄踩過格子數量為0,在點擊事件按左鍵「踩」格子時,將該變數+ 1,一直到該數加到80(100 - 20個地雷)時,表示剩下的格子全部踩過。

當兩個條件都完成的即遊戲獲勝。

以上是本次side project大致的思考過程紀錄,中間當然也有卡關的時候,卡住太久,不免我也去觀摩別人的思考思維,把東西消化後再用自己的方式呈現這次的程式碼,終於完成這個小遊戲!!!

當然這次的小專案,未來在優化的方向我想朝程式碼的可讀性與維護性上著手優化。

踩地雷小遊戲 點我試玩

謝謝耐心看完本篇~~ 有任何問題也請不吝指教,非常感謝!

--

--