카드 뒤집기 게임은 웹 개발 입문자에게 적합한 실습 프로젝트입니다. HTML, CSS, JavaScript의 기본 구조를 종합적으로 활용하며, 로직 설계, 이벤트 처리, 상태 관리, 사용자 인터랙션 등 웹 개발의 핵심 개념을 자연스럽게 익힐 수 있는 예제입니다. 본 글에서는 카드 뒤집기 게임의 HTML 기본 구조 작성, JavaScript로 게임 로직 구현, 그리고 타이머나 난이도 설정 같은 기능 확장까지 세 단계에 걸쳐 상세히 설명드리겠습니다.
HTML 구조: 레이아웃과 카드 구성의 기초
카드 뒤집기 게임을 만들기 위해 가장 먼저 해야 할 작업은 HTML을 통해 화면에 필요한 요소들을 구성하는 것입니다. 이 게임은 여러 개의 카드가 정해진 그리드 안에 배치되고, 사용자가 클릭할 때 카드가 뒤집히며, 같은 그림의 쌍을 맞추는 방식으로 진행됩니다. 따라서 HTML 구조는 그리드 레이아웃, 카드 요소, 각 카드의 앞면과 뒷면을 표현할 수 있어야 합니다.
기본적인 HTML 구조는 div 태그를 기반으로 구성됩니다. 전체 게임을 감싸는 game-board 컨테이너 안에 개별 card 요소들을 반복적으로 배치합니다. 각 카드에는 앞면(front)과 뒷면(back)을 나타내는 두 개의 내부 요소가 포함됩니다. 이러한 방식으로 게임의 시각적인 구조가 완성되며, 이후 CSS를 통해 디자인과 애니메이션을 입히게 됩니다.
예를 들어 다음과 같은 구조로 HTML을 작성할 수 있습니다:
<div class="game-board">
<div class="card">
<div class="card-front"><img src="img1.png" /></div>
<div class="card-back"></div>
</div>
</div>
여기서 card는 사용자가 클릭 가능한 전체 카드 요소이며, 내부의 card-front와 card-back은 각각 앞면과 뒷면을 구성합니다. 카드의 앞면에는 이미지가 삽입되고, 뒷면은 단색 배경이나 게임 로고 등을 넣을 수 있습니다.
카드 수는 짝수여야 하며, 각 짝마다 동일한 이미지가 매칭되도록 설정해야 게임이 제대로 작동합니다. HTML에서는 카드 정보를 하드코딩하거나 JavaScript로 생성할 수도 있지만, 초급자에게는 처음에는 하드코딩 방식이 더 이해하기 쉬운 구조입니다.
이처럼 HTML 구조를 명확하게 정의하는 것이 이후 로직 처리와 CSS 애니메이션 적용의 기초가 되며, 잘 설계된 구조는 유지보수나 기능 확장에도 큰 장점이 됩니다.
JS 로직: 카드 뒤집기와 매칭 처리
HTML과 CSS로 시각적인 구조를 만들었다면, 이제는 JavaScript로 실제 게임 로직을 구현해야 합니다. 카드가 클릭되었을 때 뒤집히는 동작, 두 장의 카드가 같을 경우 짝으로 인식되도록 하는 매칭 처리, 그리고 사용자의 입력을 제한하는 기능 등을 포함합니다.
JavaScript로 로직을 구현할 때는 다음과 같은 과정을 따라 작성하게 됩니다:
- 모든 카드 요소를 선택합니다 (document.querySelectorAll).
- 카드 클릭 시 처리할 이벤트 리스너를 등록합니다.
- 클릭한 카드가 첫 번째 카드인지 두 번째 카드인지 확인하여 상태를 기록합니다.
- 두 카드가 뒤집힌 경우, 이미지 일치 여부를 비교합니다.
- 일치하면 고정된 상태로 유지하고, 일치하지 않으면 다시 뒤집습니다.
- 이 과정에서 사용자의 추가 클릭을 잠시 막아야 하기 때문에 lockBoard 같은 논리 변수도 함께 사용합니다.
간단한 예제를 보면 다음과 같은 로직이 사용됩니다:
let firstCard, secondCard;
let lockBoard = false;
function flipCard() {
if (lockBoard || this === firstCard) return;
this.classList.add('flipped');
if (!firstCard) {
firstCard = this;
return;
}
secondCard = this;
checkForMatch();
}
function checkForMatch() {
const isMatch = firstCard.dataset.image === secondCard.dataset.image;
isMatch ? disableCards() : unflipCards();
}
function disableCards() {
firstCard.removeEventListener('click', flipCard);
secondCard.removeEventListener('click', flipCard);
resetBoard();
}
function unflipCards() {
lockBoard = true;
setTimeout(() => {
firstCard.classList.remove('flipped');
secondCard.classList.remove('flipped');
resetBoard();
}, 1000);
}
function resetBoard() {
[firstCard, secondCard, lockBoard] = [null, null, false];
}
document.querySelectorAll('.card').forEach(card => card.addEventListener('click', flipCard));
위의 코드에서는 카드에 data-image 속성을 부여하여 비교 기준을 삼고, 두 카드의 상태를 비교한 후 일치 여부에 따라 처리합니다. 이러한 방식은 DOM 요소를 직접 제어하는 연습이 되며, 로직 분리와 이벤트 흐름을 이해하는 데 효과적입니다.
기능 확장: 타이머, 점수, 난이도 추가하기
기본적인 카드 뒤집기 게임이 완성되었다면, 사용자의 몰입도를 높이고 재미를 더하기 위해 다양한 기능을 확장할 수 있습니다. 대표적인 확장 기능으로는 타이머 기능, 점수 시스템, 난이도 조절, 카드 랜덤 배치 등이 있습니다.
1. 타이머 기능
게임 시작 시 타이머가 동작하며, 완료 시간에 따라 점수 또는 별점 평가를 부여할 수 있습니다. JavaScript의 setInterval을 이용해 매초 시간을 갱신하며 화면에 표시합니다.
let time = 0;
let timer = setInterval(() => {
time++;
document.getElementById('timer').innerText = `Time: ${time}s`;
}, 1000);
게임이 끝났을 때는 clearInterval(timer)를 호출하여 타이머를 멈추면 됩니다.
2. 점수 시스템
점수는 매칭 성공 시 가산하거나, 틀렸을 경우 감산하는 방식으로 구성할 수 있습니다.
let score = 0;
function updateScore(match) {
score += match ? 10 : -5;
document.getElementById('score').innerText = `Score: ${score}`;
}
3. 난이도 설정
카드 개수를 조정하거나, 시간 제한을 두는 방식으로 난이도를 조절할 수 있습니다.
4. 카드 랜덤 배치
JavaScript의 Array.sort()와 Math.random()을 이용해 카드 배열을 섞고 DOM에 다시 렌더링하면 매번 다른 게임이 가능합니다.
기능 확장을 통해 사용자는 단순한 매칭 게임을 넘어서, 더욱 전략적이고 몰입감 있는 경험을 하게 됩니다. 또한 이 과정에서 개발자는 조건 처리, DOM 조작, 인터벌 관리, 이벤트 제어 등 다양한 웹 개발 기술을 자연스럽게 익히게 됩니다.
카드 뒤집기 게임 만들기는 웹 개발 입문자에게 HTML, CSS, JavaScript의 통합적인 구조를 실습할 수 있는 훌륭한 프로젝트입니다. 기본적인 카드 구성과 뒤집기 로직, 확장 기능을 통해 실제 사용자 경험을 고려한 코딩 역량을 키울 수 있습니다. 처음에는 간단한 구조로 시작하더라도, 꾸준히 기능을 추가하면서 웹 개발 실력을 차근차근 쌓아가시길 바랍니다.