드디어! 이 시리즈의 마지막 게시물이 업로드 되었습니다!
30개를 정리하고 꾸준히 포스팅해서.. 나름 뿌듯하네요!
마지막 게시물은 Day 30 project를 다룰건데, 굉장히 귀여운 게임을 구현했습니다.
얼른 마무리짓자구요!
랜덤으로 튀어나오는 두더지 잡기 게임을 구현해본다.
두더지는 랜덤위치에서 랜덤 시간동안 튀어나온다.
사용자가 몇마리를 잡았는지 위에 숫자로 표현한다.
상당히.. 깜찍하고 간단한 게임인 것 같네요!
const holes = document.querySelectorAll('.hole');
const scoreBoard = document.querySelector('.score');
const moles = document.querySelectorAll('.mole');
let lastHole;
let timeUp;
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 time = randomTime(200, 1000);
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;
score++;
this.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;
let score = 0;
holes
: 두더지가 속해 있는 구멍 배열을 가르킵니다. 해당 변수를 사용해서 두더지가 모습을 나타낼 곳이 어디인지 결정해요.scoreBoard
: 사용자가 몇마리의 두더지를 잡았는지 기록하기 위한 게시판을 가르키는 element입니다.moles
: 실제로 뿅 튀어나온 두더지를 가르킵니다! 총 6마리니까 querySelectorAll
이 쓰입니다.lastHole
: 두더지가 연속해서 같은 곳에서 나오지 않게 하기 위해서 필요한 변수입니다.timeUp
: 게임은 총 10초 진행됩니다. 이를 확인하기 위한 변수 flag에요.score
: 사용자가 획득한 점수를 저장한 변수입니다.startGame()
시작함수 입니다. 이 함수는 HTML
에 인라인으로 등록이 되어 있어요. 아래와 같이요!
<button onClick="startGame()">Start!</button>
따라서 Start!
버튼을 클릭하면 startGame()
이 실행됩니다.
function startGame() {
scoreBoard.textContent = 0;
timeUp = false;
score = 0;
peep();
setTimeout(() => timeUp = true, 10000)
}
먼저 점수 게시판의 내용을 초기화시킵니다!
방금 막 게임을 시작했으니, timeUp
변수를 false
로 하여 아직 시간이 끝나지 않음을 표현합니다.
이 변수는 마지막 줄에 10000밀리 세컨드가 지나고 true
가 되어, 게임이 종료됩니다.
그렇다면 그 사이에 있는 peep
함수를 살펴볼차례네요! :)
peep
함수peep
함수는 두더지가 바깥을 바라보게 하는 함수입니다!
function peep() {
const time = randomTime(200, 1000);
const hole = randomHole(holes);
hole.classList.add("up");
setTimeout(() =>{
hole.classList.remove("up");
if(!timeUp) peep();
}, time)
}
time
: randomTime
함수를 통해 200 밀리세컨드 ~ 1000밀리세컨드 사이의 값을 랜덤으로 받는 변수입니다.hole
: randomHole
함수를 통해 어느 두더지가 튀어나올지 정합니다. 단, 하나의 구멍에서 연속해서 나오는 경우는 제외해야해요!일단 time
값과 hole
값, 즉 하나의 두더지가 몇초동안 올라올건지, 어떤 두더지가 올라올건지 정해지면,
hole.classList.add("up");
setTimeout(() =>{
hole.classList.remove("up");
if(!timeUp) peep();
}, time)
up
클래스를 추가하고, time
만큼 시간이 지나면 추가했던 up
클래스를 제거합니다.
timeUp
변수가 아직 false
라면, 아직 10초가 지난것이 아니므로, 계속 게임을 해야합니다. peep
함수를 다시 실행시켜요.
randomTime
함수두더지가 얼마나 올라올건지 계산하는 함수입니다. 간단해요.
function randomTime(min, max) {
return Math.round(Math.random() * (max - min) + min);
}
Math.random()
함수는 0부터 1까지 랜덤으로 소수를 반환합니다.
여기에 저희는 min
, max
사이의 랜덤값을 구하고 싶으므로 간단한 수학 연산을 해줍니다.
(max - min)
를 곱하고 최소값인 min
을 더해줍니다. 이를 반올림하여 반환해요.
randomHole
함수어떤 두더지를 보이게 할건지, 랜덤으로 정하는 함수입니다. 단, 연속해서 하나의 구멍에서 두더지가 나오면 안돼요!
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;
}
idx
에는 6개의 구멍중 몇번째 인덱스에서 나올건지 정하는 변수가 들어갑니다.
다만, 마지막 줄에 lastHole
변수를 통해서 처음에 정해진 구멍을 저장하고, 이를 if
문을 통해서 확인합니다.
만약 랜덤으로 뽑은 hole
이 lastHole
과 같으면, 다시 randomHole
함수를 실행해 연속으로 뽑히는 상황을 방지했습니다.
bonk
함수사용자가 튀어나온 두더지를 누를때 발생하는 함수입니다.
이는 click
이벤트에 등록된 함수에요.
function bonk(e){
if(!e.isTrusted) return;
score++;
this.classList.remove("up");
scoreBoard.textContent = score;
}
moles.forEach(mole => mole.addEventListener("click", bonk));
첫번째 줄은 약간 독특한 의미가 내포되어 있습니다.
e.isTrusted
란, 해당 이벤트가 실제로 일어난 건지, 콘솔로 클릭을 유발시킨건지에 대한 정보가 저장된다고 해요.
실제로 클릭을 진행했다면 true
값으로, 아무 이상없이 통과합니다.
클릭을 진행했다는 것은, 사용자가 두더지를 잡았음을 의미하므로, score
을 증가시킵니다. 또한 두더지도 아래로 들어가므로 up
클래스를 제거하고, 증가한 score
변수를 scoreBoard
에 기록해요.
나름 간단하게 짜여진것 같아요! 기능별로 모듈화가 잘 되어 가독성도 좋았던 것 같습니다.
이렇게 javascrip30
시리즈를 끝냈습니다!
너무 뿌듯합니다 :)
이제 다른 프로젝트나 진행현황에 대해서도 연재하려고 해요! 많은 기대 부탁드립니다 :)
틀린내용이나 수정할 내용이 있다면 언제든지 피드백 부탁드립니다!
감사합니다!🤗