JavaScript30
第三十天要實作的專案是一個打地鼠的小遊戲
Github 檔案位置:30 - Whack A Mole
網站的樣子
可以先看看最後的成果
首先,先選取好今天會操作到的 DOM 元素和變數
const holes = document.querySelectorAll('.hole');
const scoreBoard = document.querySelector('.score');
const moles = document.querySelectorAll('.mole');
let lastHole; // 最後一個地鼠洞
let timeUp = false; // 遊戲進行與否
let score = 0; // 分數
這裡先來寫關於亂數的函式,我們需要一個函式名為 randomTime
決定地鼠的出現時長,以及 randomHole
決定是哪隻地鼠出現
randomHole
的實現主要是依造 holes
的陣列長度做 random,再以此索引去求出值,並紀錄最後出現的地鼠索引值,在隨機出跟上一次相同位置時重新 random
function randomTime(min, max) {
return Math.round(Math.random() * (max - min) + min);
}
function randomHole(holes) {
const idx = Math.floor(Math.random() * holes.length);
const hole = holes[idx];
if (hole === lastHole) {
console.log('Ah nah thats the same one bud');
return randomHole(holes);
}
lastHole = hole;
return hole;
}
再來就是要設定讓隨機到的地鼠出來的函式了,首先以寫好的亂數函式產生出現時長的 time
和地鼠位置的 hole
,接著再加上寫好的 CSS class,並在 time
毫秒後移除
function peep() {
const time = randomTime(200, 1000);
const hole = randomHole(holes);
hole.classList.add('up');
setTimeout(() => {
hole.classList.remove('up');
if (!timeUp) peep(); // 遊戲尚未結束因此要繼續執行
}, time);
}
再來來寫開始的函式 startGame
,主要是將遊戲設定初始化,譬如 timeUp
、score
、scoreBoard
等,並執行 peep
函式,最後以定時器來設定結束時間
function startGame() {
scoreBoard.textContent = 0;
timeUp = false;
score = 0;
peep();
setTimeout(() => timeUp = true, 10000)
}
因為在 HTML 已經綁好函式的關係,案下旁邊白色的 Start 按鈕後就會開始了
最後最後,終於要來加上打地鼠的事件啦~
以 forEach
函式幫每隻地鼠加上 click
事件,這裡的 bonk
函式邏輯非常簡單,只需要在觸發事件時移除 CSS class 並加一分更新分數即可
值得一提的是 e.isTrusted
會在以腳本觸發事件時回傳 false,可以讓使用者乖乖玩遊戲 XD
function bonk(e) {
if(!e.isTrusted) return; // cheater!
score++;
this.parentNode.classList.remove('up');
scoreBoard.textContent = score;
}
moles.forEach(mole => mole.addEventListener('click', bonk));
const holes = document.querySelectorAll('.hole');
const scoreBoard = document.querySelector('.score');
const moles = document.querySelectorAll('.mole');
let lastHole;
let timeUp = false;
let score = 0;
function randomTime(min, max) {
return Math.round(Math.random() * (max - min) + min);
}
function randomHole(holes) {
const idx = Math.floor(Math.random() * holes.length);
const hole = holes[idx];
if (hole === lastHole) {
console.log('Ah nah thats the same one bud');
return randomHole(holes);
}
lastHole = hole;
return hole;
}
function peep() {
const time = randomTime(1000, 2000);
const hole = randomHole(holes);
hole.classList.add('up');
setTimeout(() => {
hole.classList.remove('up');
if (!timeUp) peep();
}, time);
}
function startGame() {
scoreBoard.textContent = 0;
timeUp = false;
score = 0;
peep();
setTimeout(() => timeUp = true, 10000)
}
function bonk(e) {
if(!e.isTrusted) return; // cheater!
score++;
this.parentNode.classList.remove('up');
scoreBoard.textContent = score;
}
moles.forEach(mole => mole.addEventListener('click', bonk));
以上是第三十天的製作紀錄,如有錯誤或不足的地方還請多多指教 >.<
Make a Whack A Mole Game with Vanilla JS - #JavaScript30 30/30
[ Alex 宅幹嘛 ] ?? 深入淺出 Javascript30 快速導覽 | Day 30:Whack A Mole
MDN Web Docs