JS30 day30 Whack a Mole Game
JS30 day30 - Whack a Mole Game
作業內容
今天的作業是做出打地鼠的遊戲,這個練習我想主要是可以練習到遞迴的使用比較特別

學到什麼
- JS
- 第一次在 JS 裡面用到遞迴!我們如果想要每次的洞都跟上一個不同,可以做判斷,如果跟上一個一樣的話就重新跑一次本身這個函數直到不重複為止
function randomHole(holes){ const idx = Math.floor(Math.random() * holes.length) const hole = holes[idx] if(hole === lastHole){ console.log("重複了") return randomHole(holes); } lastHole = hole console.log(hole) }- 要讓地鼠不停出現,在這次也是使用遞迴的做法,在每次上一個地鼠消失的時候,如果時間還沒到就再次觸發一次這個 function 讓地鼠出現
function peep(){ const hole = randomHole(holes) const time = randomTime(200, 1000) hole.classList.add('up') setTimeout(function(){ hole.classList.remove('up') if(!timeUp) peep() }, time) }- 如果去看
click這個事件裡面的屬性,有一個isTrusted屬性,這個屬性如果是真正 user 點的才會是 true, 如果使用 JS 模擬去點的他預設會是 false
參考資料:
https://github.com/wesbos/JavaScript30
code 內容:
HTML:
<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>
CSS:
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;
}
JS:
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){
return randomHole(holes);
}
lastHole = hole
return hole
}
function peep(){
const hole = randomHole(holes)
const time = randomTime(200, 1000)
hole.classList.add('up')
setTimeout(function(){
hole.classList.remove('up')
if(!timeUp) peep()
}, time)
}
moles.forEach( mole => mole.addEventListener('click', (e)=>{
if(!e.isTrusted) return //如果不是真的 user 點的, isTrusted 這個屬性 = false(比方說 JS 點的)
score += 1
this.classList.remove('up')
scoreBoard.textContent = score
}) )
function startGame(){
scoreBoard.textContent = 0
timeUp = false
score = 0
peep()
setTimeout(()=>{ timeUp = true }, 10000)
}