JS30 day30 Whack a Mole Game

Posted by Anthony Chao on 2019-12-01

JS30 day30 - Whack a Mole Game

作業內容

今天的作業是做出打地鼠的遊戲,這個練習我想主要是可以練習到遞迴的使用比較特別

學到什麼

  • JS

    1. 第一次在 JS 裡面用到遞迴!我們如果想要每次的洞都跟上一個不同,可以做判斷,如果跟上一個一樣的話就重新跑一次本身這個函數直到不重複為止
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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)
    }
    1. 要讓地鼠不停出現,在這次也是使用遞迴的做法,在每次上一個地鼠消失的時候,如果時間還沒到就再次觸發一次這個 function 讓地鼠出現
    1
    2
    3
    4
    5
    6
    7
    8
    9
    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)
    }
    1. 如果去看 click 這個事件裡面的屬性,有一個 isTrusted 屬性,這個屬性如果是真正 user 點的才會是 true, 如果使用 JS 模擬去點的他預設會是 false

參考資料:
https://github.com/wesbos/JavaScript30

code 內容:

HTML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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)
}




prevent_hack