【實作記錄】Pacman Game | Vanilla JS
簡介
這是一款使用 JavaScript 製作的小精靈遊戲。玩家將所有點點吃完便會獲勝、被精靈吃掉遊戲便結束。點點分數為 1 分、大點點 (power pallet) 為 10 分、吃掉害怕狀態的精靈增加 100 分。其中也添加了音效,默認為關閉,可點擊右上的 “volume icon” 打開。
功能
- 使用上下左右鍵移動 Pacman
- 吃了 Power Pallet 便可以吃掉顏色為橘色的精靈
- 每個動作都有音效,可以透過右上的 “volume icon” 關閉
- 吃完點點便會宣佈獲勝
- 被精靈吃掉,遊戲便結束
小筆記
Pacman 的移動
Pacman 的上下移動邏輯使用 switch 處理。判斷 pacman 在移動的時候是否碰到墻壁,若沒有碰到墻壁/沒有碰到精靈則可以往按鍵的方向行動。
- 判斷是否碰到墻壁:如果要往下的那個沒有 “wall” 這個 class ,表示沒有
- 判斷是否碰到精靈:如果要往下的那個沒有 “ghost” 這個 class ,表示沒有
keycode | 移動方式 | 判斷方式 | |
---|---|---|---|
40 | 往下鍵 | pacman 所在的位置 + width | 判斷是否已經到最底層:如果 pacman 所在 index 加上 width 小於整個 layout 的最大 index, 表示沒有超出邊界 |
38 | 往上鍵 | pacman 所在的位置 - width | 判斷是否已經到最上層:如果 pacman 所在 index 減掉 width 小於整個 0, 表示沒有超出邊界 |
37 | 往左鍵 | pacman 所在的位置 -1 | 判斷是否已經到最左邊:如果 pacman 所在 index 除 width 的餘數不等於 0, 表示沒有超出邊界 |
38 | 往由鍵 | pacman 所在的位置 +1 | 判斷是否已經到最左邊:如果 pacman 所在 index 除 width 的餘數小於 width - 1, 表示沒有超出邊界 |
1 | switch(e.keyCode) { |
精靈的 class
由於 4 個精靈是一組的,都有 className 、起始位置、移動速度、當下位置、是否為害怕狀態、計時器,因此使用 class 來處理。需要每一隻精靈執行共同的程式碼就使用 for Each.
1 | class Ghost{ |
- 把精靈畫進 grid 裡
1
2
3ghosts.forEach (ghost => {
squares[ghost.currentIndex].classList.add(ghost.className)
squares[ghost.currentIndex].classList.add("ghost")
精靈移動
使用 Math.random() 決定精靈移動的方向,因此方向是沒有邏輯的
1
2const directions = [-1 , +1 , -width , +width]
let direction= directions[Math.floor(Math.random() * directions.length)]沒有碰到碰到精靈或墻壁,就可以往隨機選出來的方向前進一格
1
2
3
4
5
6
7
8
9
10
11if (
!squares[ghost.currentIndex + direction].classList.contains("wall") &&
!squares[ghost.currentIndex + direction].classList.contains("ghost")
){
squares[ghost.currentIndex].classList.remove(ghost.className)
squares[ghost.currentIndex].classList.remove("ghost", "scared-ghost")
ghost.currentIndex += direction
squares[ghost.currentIndex].classList.add(ghost.className)
squares[ghost.currentIndex].classList.add("ghost")
}在吃了 power pallet 之後,精靈會轉為 scared 狀態,就可以被吃
- this.isScared = true
- 會轉為橘色
1
2
3
4
5
6
7
8
9if (
ghost.isScared && squares[ghost.currentIndex].classList.contains("pacman")
){
squares[ghost.currentIndex].classList.remove(ghost.className,"scared-ghost")
ghost.currentIndex = ghost.startIndex
score += 100
squares[ghost.currentIndex].classList.add(ghost.className , "ghost")
eatGhostSound()
}
遊戲結束
- 碰到精靈遊戲便會結束
- 計時器會被清除,按鍵被移除,game over 字樣出現
1
2
3
4
5
6
7
8
9if (
!ghost.isScared && squares[ghost.currentIndex].classList.contains("pacman")
){
ghosts.forEach(ghost => clearInterval(ghost.timerId))
document.removeEventListener("keydown", control)
gameOver.style.display = "block"
overlay.style.display="block"
deathSound()
}
玩家贏了
- 吃完所有點點就宣佈獲勝
1
2
3
4
5
6
7
8
9
10
11let dot = 305
function win(){
if( dot === 0){
ghosts.forEach(ghost => clearInterval(ghost.timerId))
document.removeEventListener("keydown", control)
gameWin.style.display = "block"
overlay.style.display="block"
winSound()
}
}
小結
這個小遊戲中練習了 class 以及 switch. 這裡沒有處理精靈移動的邏輯,原本應該追著 / 包抄 pacman, 但因為是使用隨機方向,因此精靈們看起來很笨(扶額)。這個部分等我找到比較好的方式再來看看怎麼讓他們聰明一些。畫地圖是使用 excel 先畫一遍,再把他們轉為 index,才填上顏色。
這篇筆記為個人學習記錄,若有錯誤或是可以改進的地方再麻煩各位大大指點(鞠躬