소개
이 프로젝트에서는 HTML, CSS, JavaScript 를 사용하여 Whack-a-Mole 게임을 만드는 방법을 배웁니다. 이 게임은 지정된 시간 제한 내에 구멍에서 무작위로 나타나는 두더지를 때리는 방식으로 진행됩니다. 필요한 HTML, CSS 및 JavaScript 파일을 만들고 게임 로직을 단계별로 구현합니다.
👀 미리보기

🎯 과제
이 프로젝트에서 다음을 배우게 됩니다:
- Whack-a-Mole 게임을 위한 프로젝트 파일을 설정하는 방법
- 게임 레이아웃 및 디자인을 만들기 위해 필요한 CSS 스타일을 추가하는 방법
- 두더지가 나타나고 사라지게 하고, 점수를 유지하며, 시간을 추적하는 게임 로직을 구현하는 방법
- 두더지를 때리고 게임을 시작하기 위한 이벤트 리스너를 만드는 방법
🏆 성과
이 프로젝트를 완료하면 다음을 수행할 수 있습니다:
- 웹 기반 게임을 위한 HTML, CSS 및 JavaScript 파일을 생성합니다.
- CSS 를 사용하여 게임 요소를 스타일링하고 레이아웃합니다.
- JavaScript 를 사용하여 DOM 을 조작하여 게임 요소를 나타내고 사라지게 합니다.
- 사용자 상호 작용을 처리하고 게임 상태를 업데이트합니다.
- JavaScript 의 타이머를 사용하여 시간을 추적하고 게임 흐름을 제어합니다.
프로젝트 파일 생성
먼저, Whack-a-Mole 게임을 위한 프로젝트 파일을 생성해 보겠습니다.
~/project디렉토리로cd합니다.index.html이라는 새 파일을 생성합니다.- 다음 코드를 복사하여
index.html에 붙여넣습니다:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css"
rel="stylesheet"
/>
<link rel="stylesheet" href="styles.css" />
<title>Whack-a-Mole!</title>
</head>
<body
class="bg-gradient-to-r from-yellow-400 via-red-500 to-pink-500 flex items-center justify-center h-screen"
>
<div class="game bg-white p-8 rounded-lg shadow-2xl text-center">
<h1 class="text-4xl font-bold mb-4 text-red-600">Whack-a-Mole!</h1>
<p class="score text-2xl text-red-600">
Score: <span id="score">0</span>
</p>
<p class="time text-2xl text-red-600">
Time Left: <span id="time">0</span>
</p>
<button
id="startBtn"
class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded mt-4 transition duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-110"
>
Start Game
</button>
<div id="grid" class="grid grid-cols-3 gap-4 mt-4">
<!-- Holes will be added here -->
</div>
</div>
<script src="main.js"></script>
</body>
</html>
CSS 스타일 추가
styles.css라는 새 파일을 생성합니다.- 다음 코드를 복사하여
styles.css에 붙여넣습니다:
.game {
width: 600px;
border-radius: 2rem;
}
.hole {
height: 0;
padding-bottom: 100%;
position: relative;
background: #eee;
border: 3px solid #ccc;
border-radius: 50%;
overflow: hidden;
}
.mole {
width: 100%;
height: 100%;
background: #a0522d;
border-radius: 50%;
position: absolute;
transform: translateY(100%);
transition: transform 0.3s;
}
.mole.up {
transform: translateY(0);
}
.mole.whacked {
background: #008cff;
}
#startBtn {
background-color: #0051ff;
color: #fff;
padding: 10px 20px;
border-radius: 20px;
border: none;
cursor: pointer;
transition: background-color 0.3s;
}
#startBtn:hover {
background-color: #028a5f;
}
게임 로직 추가
main.js라는 새 파일을 생성합니다.- 다음 단계에서 JavaScript 코드를 추가할 것입니다.
이제 main.js 파일에 게임 로직을 추가해 보겠습니다.
main.js파일을 엽니다.- 다음 코드를 복사하여
main.js에 붙여넣습니다:
const grid = document.querySelector("#grid");
const scoreDisplay = document.querySelector("#score");
const timeDisplay = document.querySelector("#time");
const startBtn = document.querySelector("#startBtn");
let holes = [];
let score = 0;
let lastHole;
let timeUp = false;
let gameTimer;
let countdownTimer;
let countdown;
function createHoles() {
for (let i = 0; i < 6; i++) {
const hole = document.createElement("div");
const mole = document.createElement("div");
hole.classList.add("hole");
mole.classList.add("mole");
hole.appendChild(mole);
grid.appendChild(hole);
holes.push(hole);
}
}
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() {
// TODO: Implement this function in Step 3.
}
function startGame() {
// TODO: Implement this function in Step 4.
}
function whack(e) {
// TODO: Implement this function in Step 5.
}
createHoles();
// TODO: Implement the rest of the code in Step 6.
이 코드는 다양한 HTML 요소에 대한 참조를 저장하는 변수를 정의하고 다른 필요한 변수를 초기화합니다. 또한 구멍을 생성하고, 임의의 시간과 구멍을 생성하고, 두더지를 나타내고 사라지게 하고, 게임을 시작하고, 두더지 때리기를 처리하기 위한 여러 함수를 정의합니다. 마지막으로 구멍을 생성하고, 구멍에 이벤트 리스너를 추가하고, 시작 버튼 클릭 이벤트 리스너를 설정합니다.
peep 함수 구현
이 단계에서는 두더지가 무작위로 나타나고 사라지도록 하는 peep 함수를 구현합니다.
main.js파일을 엽니다.peep함수를 찾습니다.- 기존 코드를 다음 코드로 바꿉니다:
function peep() {
const time = randomTime(200, 1000);
const hole = randomHole(holes);
hole.querySelector(".mole").classList.add("up");
setTimeout(() => {
hole.querySelector(".mole").classList.remove("up");
hole.querySelector(".mole").classList.remove("whacked");
if (!timeUp) peep();
}, time);
}
이 함수는 randomTime 함수를 사용하여 200ms 에서 1000ms 사이의 임의의 시간 간격을 설정합니다. randomHole 함수를 사용하여 임의의 구멍을 선택하고, up 클래스를 mole 요소에 추가하여 두더지를 나타나게 합니다. 지정된 시간 간격이 지나면 up 클래스를 제거하여 두더지가 사라집니다. 게임이 끝나지 않은 경우 (timeUp이 false인 경우) 함수는 자체적으로 재귀 호출하여 다른 두더지를 나타나게 합니다.
startGame 함수 구현
다음으로, 게임을 초기화하고 타이머를 시작하는 startGame 함수를 구현합니다.
main.js파일을 엽니다.startGame함수를 찾습니다.- 기존 코드를 다음 코드로 바꿉니다:
function startGame() {
scoreDisplay.textContent = 0;
timeUp = false;
score = 0;
peep();
gameTimer = setTimeout(() => (timeUp = true), 10000);
countdown = 10;
timeDisplay.textContent = countdown;
startBtn.disabled = true;
countdownTimer = setInterval(() => {
countdown--;
if (countdown < 0) {
clearInterval(countdownTimer);
startBtn.disabled = false;
return;
}
timeDisplay.textContent = countdown;
}, 1000);
}
이 함수는 점수를 초기화하고, timeUp을 false로 설정하고, 점수 표시를 재설정합니다. peep 함수를 호출하여 두더지 나타나기를 시작합니다. setTimeout을 사용하여 게임 타이머를 시작하여 10 초 후에 timeUp을 true로 설정합니다. 또한 매 초마다 시간 표시를 업데이트하기 위해 카운트다운 타이머를 설정합니다. 카운트다운은 처음에 10 으로 설정되며, 0 에 도달하면 카운트다운 타이머가 지워지고, 시작 버튼이 활성화되며, 함수가 반환됩니다.
whack 함수 구현
이제 두더지를 때리고 점수를 업데이트하는 whack 함수를 구현해 보겠습니다.
main.js파일을 엽니다.whack함수를 찾습니다.- 기존 코드를 다음 코드로 바꿉니다:
function whack(e) {
if (!e.isTrusted || !this.querySelector(".mole").classList.contains("up"))
return; // fake click detected or the mole is not up
score++;
this.querySelector(".mole").classList.remove("up");
this.querySelector(".mole").classList.add("whacked");
scoreDisplay.textContent = score;
}
이 함수는 두더지를 클릭했을 때 호출됩니다. 가짜 클릭을 방지하기 위해 클릭 이벤트가 신뢰할 수 있는지 (e.isTrusted) 확인합니다. 또한 up 클래스가 있는지 확인하여 두더지가 현재 올라와 있는지 확인합니다. 클릭이 유효하면 점수를 증가시키고, mole 요소에서 up 클래스를 제거하고, 두더지가 때려졌음을 시각적으로 나타내기 위해 whacked 클래스를 추가하고, 점수 표시를 업데이트합니다.
게임 초기화 및 이벤트 리스너 설정
이 단계에서는 구멍을 생성하고 구멍과 시작 버튼에 이벤트 리스너를 추가하여 게임을 초기화합니다.
main.js파일을 엽니다.createHoles()함수 호출이 있는 줄을 찾습니다.createHoles()함수 호출 뒤에 다음 코드를 추가합니다:
holes.forEach((hole) => hole.addEventListener("click", whack));
startBtn.addEventListener("click", startGame);
이 코드는 각 구멍 요소에 클릭 이벤트 리스너를 추가합니다. 구멍을 클릭하면 whack 함수가 호출됩니다. 또한 시작 버튼에 클릭 이벤트 리스너를 추가하여 클릭 시 startGame 함수를 호출합니다.
Whack-a-Mole 게임 테스트
WebIDE 오른쪽 하단 모서리에 있는 Go Live 버튼을 클릭하고 Web 8080 탭으로 전환합니다.

그러면 프로젝트가 Web 8080 탭에서 열립니다.

요약
이 프로젝트에서는 Whack-a-Mole 게임의 프로젝트 파일을 생성했습니다. HTML 구조를 만들고, CSS 스타일을 추가했으며, JavaScript 를 사용하여 게임 로직을 구현했습니다. 다음 단계는 사운드, 레벨 및 난이도 설정을 추가하는 등 게임을 추가로 사용자 정의하고 향상시키는 것입니다.



