俗話說的好,一天一蘋果,醫生遠離我
一天一 JS,What the f*ck JavaScript?
small steps every day - 記錄著新手村日記
做一個打地鼠的遊戲
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Whack A Mole!</title>
<link href='https://fonts.googleapis.com/css?family=Amatic+SC:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Whack-a-mole! <span class="score">0</span></h1>
<button onClick="startGame()">Start!</button>
<div class="game">
<div class="hole hole1">
<div class="mole"></div>
</div>
<div class="hole hole2">
<div class="mole"></div>
</div>
<div class="hole hole3">
<div class="mole"></div>
</div>
<div class="hole hole4">
<div class="mole"></div>
</div>
<div class="hole hole5">
<div class="mole"></div>
</div>
<div class="hole hole6">
<div class="mole"></div>
</div>
</div>
<script>
const holes = document.querySelectorAll('.hole');
const scoreBoard = document.querySelector('.score');
const moles = document.querySelectorAll('.mole');
</script>
</body>
</html>
html {
box-sizing: border-box;
font-size: 10px;
background: #ffc600;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
padding: 0;
margin: 0;
font-family: 'Amatic SC', cursive;
}
h1 {
text-align: center;
font-size: 10rem;
line-height: 1;
margin-bottom: 0;
}
.score {
background: rgba(255,255,255,0.2);
padding: 0 3rem;
line-height: 1;
border-radius: 1rem;
}
.game {
width: 600px;
height: 400px;
display: flex;
flex-wrap: wrap;
margin: 0 auto;
}
.hole {
flex: 1 0 33.33%;
overflow: hidden;
position: relative;
}
.hole:after {
display: block;
background: url(dirt.svg) bottom center no-repeat;
background-size: contain;
content: '';
width: 100%;
height:70px;
position: absolute;
z-index: 2;
bottom: -30px;
}
.mole {
background: url('mole.svg') bottom center no-repeat;
background-size: 60%;
position: absolute;
top: 100%;
width: 100%;
height: 100%;
transition:all 0.4s;
}
.hole.up .mole {
top: 0;
}
首先,我們先將需要的元素選取起來,必須先找到地鼠洞的List、地鼠圖的List、 span
的數量
<script>
const holes = document.querySelectorAll('.hole');
const scoreBoard = document.querySelector('.score');
const moles = document.querySelectorAll('.mole');
console.log(holes)
console.log(scoreBoard)
console.log(moles)
</script>
先來製作一個函式,讓這個函式執行後有一個上下限的隨機時間
<script>
const holes = document.querySelectorAll('.hole');
const scoreBoard = document.querySelector('.score');
const moles = document.querySelectorAll('.mole');
function randomTime(min, max) {
let time = Math.floor(Math.random() * (max - min) + min);
return time
};
</script>
接下來,我們來取得隨機一個 hole
元素,如果與上一次取到的相同,我們就再次執行一次隨機選取的函式,不同的話就把現在的Hole指定給變數 lastHole
<script>
const holes = document.querySelectorAll('.hole');
const scoreBoard = document.querySelector('.score');
const moles = document.querySelectorAll('.mole');
function randomTime(min, max) {
let time = Math.floor(Math.random() * (max - min) + min);
return time
};
let lastHole;
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;
}
</script>
時間都處理完畢後,我們要來來地鼠可以從地鼠洞跑出來,在前面的CSS當中可以知道,地鼠的一開始是被做了相對定位並 top:100%
及 overflow:hidden
起來了!因此剛開始的時候地鼠其實是偷偷躲在底下的w
現在只要判斷什麼時候加上一個 Class 讓地鼠從地鼠洞出來以及多久會從地鼠洞出來一次,要新增&移除 Class
<script>
//上略
let timeUp = false;
function peep() {
const time = randomTime(200, 1000);
const hole = randomHole(holes);
hole.classList.add('up');
setTimeout(() => {
hole.classList.remove('up');
if (!timeUp) peep();
}, time);
}
</script>
最後,再加上遊戲開始及點到一個就增加分數吧!這部分比較單純只要將 score
宣告變數出來,以及點到分數++就可以,然後趕緊來打地鼠吧w
<script>
//上略
moles.forEach(mole => mole.addEventListener('click', bonk));
function bonk(e) {
if(!e.isTrusted) return; // cheater!
score++;
this.parentNode.classList.remove('up');
scoreBoard.textContent = score;
}
function startGame() {
scoreBoard.textContent = 0;
timeUp = false;
score = 0;
peep();
setTimeout(() => timeUp = true, 10000)
}
</script>
就大功告成啦!
<script>
const holes = document.querySelectorAll('.hole');
const scoreBoard = document.querySelector('.score');
const moles = document.querySelectorAll('.mole');
function randomTime(min, max) {
let time = Math.floor(Math.random() * (max - min) + min);
return time
};
let lastHole;
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(200, 1000);
const hole = randomHole(holes);
hole.classList.add('up');
setTimeout(() => {
hole.classList.remove('up');
if (!timeUp) peep();
}, time);
}
moles.forEach(mole => mole.addEventListener('click', bonk));
function bonk(e) {
if(!e.isTrusted) return; // cheater!
score++;
this.parentNode.classList.remove('up');
scoreBoard.textContent = score;
}
function startGame() {
scoreBoard.textContent = 0;
timeUp = false;
score = 0;
peep();
setTimeout(() => timeUp = true, 10000)
}
</script>
本刊同步於個人網站:http://chestertang.site/
本次範例程式碼原作者來源:https://tinyurl.com/yavm5f5n