JS30 Day 30 筆記


Posted by GL on 2023-05-23

目標

製作一個打地鼠遊戲

Demo

step 1 : 取得 HTML 頁面元素

const holes = document.querySelectorAll('.hole');
const scoreBoard = document.querySelector('.score');
const moles = document.querySelectorAll('.mole');

step 2 : 預設的設定

/** 預設變數設定 */
let lastHole; // 最後一次出現的洞
let timeUP = false; // 是否到遊戲結束時間
let score = 0; // 玩家總得分
let gameTime = 10000 // 每次遊戲的總時間

step 3 : 監聽 start 按鈕,點擊後開始新遊戲

// 設定初始值
function startGame(){
  // 重置得分榜顯示的得分
  scoreBoard.textContent = 0
  // 重置結束時間為 false
  timeUp = false
  // 重置得分
  score = 0
  // 開始遊戲,讓地鼠隨機出現
  peep()
  // 等到過了 gameTime 時間後, 讓結束時間為 true
  setTimeout(() => timeUp = true, gameTime)
}

// 監聽 start 按鈕,點擊之後觸發 startGame function
document.querySelector('.start').addEventListener('click',startGame)

step 4 : 設定地鼠隨機出現的洞,以及停留隨機時間

Math.random() 隨機回傳 0~1 之間的一個隨機小數(包含 0,不包含 1)

function randomTime(min, max) {
  // 設定亂數最大值與最小值區間,取得地鼠隨機出現的時間長
  return Math.round(Math.random() * (max - min) + min);
}

function randomHole(holes) {
  // 拿到所有洞的數量,然後透過亂數取得隨機的洞口的 index
  const idx = Math.floor(Math.random() * holes.length);
  // 有了隨機的 index 後確定是第幾個洞口
  const hole = holes[idx];

  // 避免地鼠連續兩次都從同一個洞口出現,
  if (hole === lastHole) {
    return randomHole(holes);
  }
  // 記錄最後出現的地鼠洞口
  lastHole = hole;
  return hole;
}

step 5 :地鼠出現

function peep() {
  // 設定地鼠隨機出現的時間長
  const time = randomTime(200, 1000);
  // 設定地鼠隨機出現的洞
  const hole = randomHole(holes);;
  // 添加出現的 class
  hole.classList.add('up');

  // 設定存在時間到的時候移除出現動畫,且若遊戲時間未結束就繼續跑下一run
  setTimeout(() => {
    hole.classList.remove('up');
    if (!timeUP) peep();
  }, time)
}

step 6 : 打地鼠

isTrusted:若事件是由使用者操作而產生,則 isTrusted 為 true。若事件物件是由程式碼所建立、修改,或是透過 EventTarget.dispatchEvent() 來觸發,則 isTrusted 值為 false。

function bonk(e) {
  // isTrusted 防止非使用者操作而產生
  if(!e.isTrusted) return;
  // 點到地鼠之後得分加 1
  score ++
  // 點到地鼠之後把 class name = up 拿掉
  this.parentNode.classList.remove('up')
  // 將得分顯示在得分欄中
  scoreBoard.textContent = score
}

//  在每一個地鼠監聽 click 事件,點擊時觸發 bonk function
moles.forEach(mole=>{
  mole.addEventListener('click',bonk)
})

參考資料:


#JS 30







Related Posts

Training with Different Image Shapes

Training with Different Image Shapes

Kotlin 讀書會

Kotlin 讀書會

Gzip + kNN: A Good Text Classifier?

Gzip + kNN: A Good Text Classifier?


Comments