iT邦幫忙

2024 iThome 鐵人賽

DAY 30
0

Whack a mole! 冒版打地鼠

按下開始按鈕後,地鼠就會一直冒出來,同時間螢幕會顯示倒數的秒數,每打到一次地鼠就會加分,分數也要同時顯示在畫面。時間到之後,就不能再有地鼠跑出來。

有結合到了上一篇倒數計時的概念new Date()。

https://ithelp.ithome.com.tw/upload/images/20241009/201691741V5kTghoip.png

個人codepen

技巧點

主要行為是地鼠要隨機冒出來,並且要第一隻地鼠回去後,第二隻才能出來。

// 選取所有地鼠洞,裡面包含了地鼠。
const holes = document.querySelectorAll(".hole");

// 取得隨機數的方法,根據傳入的最小和最大值,回傳介於這區間的隨機數字
function random(min, max) {
  return Math.round(Math.random() * (max - min) + min);
}

// 控制地鼠隨機出現
function popup() {
  // 隨機秒數,用於定時器
  const timeNum = random(200, 800);
  
  // holes是一個node List,可以像陣列一樣用索引值取特定的元素,利用亂數取到隨機的索引值
  const holeNum = random(0, holes.length -1);
  
  // 將地鼠加上class名稱,在class那邊操作top讓他蹦出來
  holes[holeNum].classList.add("active");
  
  // 地鼠出來後,要讓他再回去,因此多久之後要讓他回去,是隨機的。設定計時器,每間隔隨機的秒數,就會把active移除,地鼠就會回去了。回去後,代表下一隻地鼠可以出現,所以再次執行popup方法。就可以達成循環的地鼠一直冒出來。
  const timer = setTimeout(() => {
    holes[holeNum].classList.remove("active");
    
    // 遊戲持續中才能繼續讓地鼠出來,isPlay會在倒數計時那邊控制結束
    isPlay && popup();
  }, timeNum);
}

地鼠可以循換出現後,點擊地鼠應該要加分數。所以每隻地鼠要額外綁定監聽,確認是否被點擊。

// 所有地鼠綁定點擊事件監聽器
const moles = document.querySelectorAll(".mole");
moles.forEach(item => item.addEventListener("click", whack));

// 點到地鼠,就加上分數,並且將分數渲染在畫面。另外點到地鼠後,要讓他回去。
let scores = 0;
function whack(e) {
  scores += 10;
  displayScore(scores);
  
  // this指向為mole元素,mole元素是包覆在hole元素底下,所以parentNode可以取到父元素,再把父元素的active移除即可。
  this.parentNode.classList.remove("active")
}

// 處理畫面分數
const score = document.querySelector(".score");
function displayScore(point) {
  score.textContent = point;
}

處理按下開始鍵後地鼠才能循環出現。

// 開始按鈕綁定監聽
const startBtn = document.querySelector(".start");
startBtn.addEventListener("click", start);


let isPlay = false;
function start() {
  // 控制開始按鈕,在開始後再次點擊也不會觸發
  if (isPlay) return;
  isPlay = true;
  
  // 每次開始分數要歸零
  scores = 0;
  displayScore(scores);
  
  // 倒數計時
  countDown();
  
  // 開始按鈕文字要轉換成遊戲中
  startBtn.textContent = "playing";
  
  // 地鼠出現
  popup();
}

// 倒數計時器
function countDown() {
  // 這邊的10為遊戲只有10秒的時間,要轉換成毫秒,加上目前的時間,可以得知遊戲結束的時間。
  const then = Date.now() + 10 * 1000;
  
  // 處理目前剩幾秒,將遊戲結束時間跟現在的時間做相減,就知道遊戲剩下幾秒。因為遊戲結束時間是不會變動的,但現在的時間會一直動。就可以計算倒數時間。
  const remainingSec = Math.round((then - Date.now()) / 1000);
  displayTime(remainingSec);
  const timer = setInterval(() => {
    const remainingSec = Math.round((then - Date.now()) / 1000);
    
    // 當倒數為0秒時,就要關掉地鼠出現
    if (remainingSec === 0) isPlay = false;
    
    // 秒數小於0,要清楚倒數計時器
    if (remainingSec < 0) {
      clearInterval(timer);
      startBtn.textContent = "start";
      return;
    }
    
    // 處理倒數時間的畫面
    displayTime(remainingSec);
  }, 1000);
}

function displayTime(sec) {
  countdownTxt.textContent = `00:${sec}`;
}

心得

看影片中有寫到isTrusted,是一個布林值。用來判斷是不是使用者操作而觸發的行為,如果是使用者觸發為true;如果是用程式碼修改的話為false。
看起來是一個防止用程式碼作弊的判斷。幸好我的打地鼠沒有在營業賺錢,所以沒關係哈哈😂

另外地鼠可不可以連續從一個洞出來,不行的話,就必須加上判斷。把當下出來的地鼠存起來,要跳下一隻地鼠的時候,判斷是否重複。重複的話要重新跑一次方法popup()。


上一篇
Countdown Clock
系列文
鱷魚帶我練習JavaScript之個人練功坊30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言