반응형
Web Development · JavaScript Game
JavaScript 알까기 게임 - 랜덤 배치와 타이머 완전 정리
숨겨진 정답 위치를 기억하고 맞히는 게임으로 배열, 랜덤, 타이머, 클릭 이벤트 흐름을 정리합니다.
1 원본 코드가 만드는 게임 흐름
이 예제는 24개의 이미지 칸 중 일부 칸을 정답으로 표시한 뒤, 일정 시간이 지나면 다시 숨기고 사용자가 기억한 위치를 클릭하게 만드는 게임이다. 핵심은 정답 위치를 화면에만 표시하는 것이 아니라 mark 배열에도 같이 기록해 두는 것이다.
게임 시작
정답 랜덤 배치
기억 시간 진행
정답 숨김
클릭 판정
화면의 이미지는 계속 바뀌지만 실제 정답 여부는
mark[index]에 남는다. 게임 로직에서는 화면 상태보다 데이터 상태를 기준으로 판정해야 한다.2 주요 변수 역할
mark 배열 각 칸이 정답인지 아닌지를 저장한다. true면 숨겨진 강아지 또는 정답 위치, false면 일반 위치다.
timerID
setInterval()이 반환한 값을 보관한다. 단계가 바뀌거나 게임이 끝날 때 clearInterval()로 멈춘다.restNum 아직 찾지 못한 정답 개수다. 정답을 클릭할 때마다 1씩 줄고 0이 되면 승리한다.
failNum 오답 클릭 횟수다. 허용 횟수에 도달하면 실패로 게임을 종료한다.
const mark = new Array(24); let timerID = null; const NOOFANSWER = 8; const MAXTRY = 5; const FINDINGSECONDS = 20; const THINKSECONDS = 10; let restNum; let failNum = 0; let watingSeconds;
원본 변수명은
watingSeconds로 되어 있다. 동작에는 문제가 없지만 실제 프로젝트라면 waitingSeconds처럼 오타를 줄인 이름이 좋다.3 정답 위치를 중복 없이 섞는 방법
정답을 8개 배치하려면 단순히 8번 랜덤 숫자를 뽑는 것만으로는 부족하다. 같은 칸이 여러 번 뽑힐 수 있기 때문이다. 그래서 랜덤 인덱스를 뽑은 뒤 이미 정답인지 검사하고, 아직 정답이 아닌 위치일 때만 i++를 실행한다.
// 모든 칸을 일반 상태로 초기화 for (let i = 0; i < mark.length; i++) { mark[i] = false; document.images[i].src = "media/img1.gif"; document.images[i].style.borderWidth = "0px"; } // 아직 정답으로 쓰이지 않은 위치만 선택 for (let i = 0; i < NOOFANSWER;) { let index = Math.floor(Math.random() * 24); if (mark[index] !== true) { mark[index] = true; document.images[index].src = "media/img2.gif"; i++; } }
이 구조의 핵심은 반복 횟수와 성공 횟수를 분리하는 것이다. 랜덤으로 이미 뽑힌 칸이 나오면 반복은 다시 돌지만 성공 개수는 늘리지 않는다.
반응형
4 타이머로 기억 단계와 찾기 단계를 나누기
게임은 두 개의 시간 구간을 가진다. 처음에는 사용자가 정답 위치를 기억하는 시간이고, 그 다음에는 숨겨진 정답을 찾는 시간이다. 단계가 바뀔 때 기존 타이머를 정리하지 않으면 같은 함수가 계속 중복 실행될 수 있다.
function thinkTime() { watingSeconds--; timeObj.innerText = "남은 시간 : " + watingSeconds; if (watingSeconds === 0) { playsound("media/bi.mp3"); hideAnswer(); } } function hideAnswer() { clearInterval(timerID); for (let i = 0; i < document.images.length; i++) { document.images[i].src = "media/img1.gif"; document.images[i].onclick = checkAnswer; } watingSeconds = FINDINGSECONDS; resultObj.innerHTML = "정답을 찾으세요"; timerID = setInterval("findTime()", 1000); }
원본처럼
setInterval("thinkTime()", 1000) 형태로 문자열을 넘겨도 실행은 된다. 다만 일반적으로는 setInterval(thinkTime, 1000)처럼 함수 자체를 넘기는 방식이 더 안전하고 읽기 쉽다.5 클릭한 이미지의 인덱스 찾기
checkAnswer(e)는 클릭 이벤트 객체를 받아서 어떤 이미지가 클릭됐는지 찾는다. 원본 코드는 document.images 전체를 순회하면서 e.target과 같은 객체를 찾고, 그 위치를 인덱스로 사용한다.
function checkAnswer(e) { let clickIndex = -1; for (let i = 0; i < document.images.length; i++) { if (e.target === document.images[i]) { clickIndex = i; break; } } if (mark[clickIndex] === true) { mark[clickIndex] = false; document.images[clickIndex].src = "media/img2.gif"; document.images[clickIndex].onclick = null; restNum--; } else { failNum++; } }
| 판정 | 조건 | 처리 |
|---|---|---|
| 정답 클릭 | mark[clickIndex] === true |
정답 표시, 클릭 비활성화, 남은 정답 수 감소 |
| 오답 클릭 | mark[clickIndex] === false |
실패 횟수 증가, 최대 실패 횟수 도달 시 게임 종료 |
| 모두 찾음 | restNum === 0 |
승리 메시지 출력, 타이머 정지, 클릭 비활성화 |
| 시간 초과 | watingSeconds === 0 |
실패 처리 후 숨겨진 정답 위치 공개 |
6 바로 실행해보는 미니 데모
아래 데모는 원본의 핵심 흐름만 페이지 안에서 바로 확인할 수 있게 다시 구성한 것이다. 실제 이미지 파일과 오디오 파일 없이도 동작하도록 CSS로 알 모양을 만들었다.
남은 답: 8 실패: 0/5 시간: -- 대기
초록색은 기억 단계의 정답, 파란색은 맞힌 칸, 빨간색은 오답입니다.
7 자주 나는 실수
| 실수 | 증상 | 해결 |
|---|---|---|
| 타이머를 정리하지 않음 | 시간이 2초씩 줄거나 게임 종료 뒤에도 함수가 계속 실행됨 | 단계 전환과 종료 시 clearInterval(timerID)를 호출한다. |
| 정답 클릭 뒤 이벤트를 유지함 | 같은 정답을 여러 번 클릭해서 남은 개수가 음수가 될 수 있음 | 맞힌 칸은 onclick = null로 다시 클릭하지 못하게 한다. |
| 랜덤 중복을 검사하지 않음 | 정답 개수가 설정값보다 적게 배치됨 | mark[index]를 확인하고 비어 있을 때만 개수를 증가시킨다. |
| 화면 이미지 상태만 믿음 | 이미지를 숨긴 뒤 정답 여부를 판정할 수 없음 | 화면과 별도로 mark 배열에 정답 정보를 보관한다. |
핵심 요약
mark[index] 정답 위치를 저장하는 게임의 실제 데이터다. 화면이 숨겨져도 판정 기준은 배열에 남는다.
Math.random() 랜덤 인덱스를 만들 때 사용한다. 중복 검사를 함께 해야 원하는 개수만큼 정확히 배치된다.
setInterval() 기억 시간과 찾기 시간을 1초 단위로 줄인다. 단계가 바뀔 때는 기존 타이머를 반드시 멈춘다.
onclick = null 찾은 칸이나 게임 종료 후의 칸을 다시 클릭하지 못하게 만들어 점수 오류를 막는다.
Tags
#JavaScript #알까기게임 #기억력게임 #setInterval #clearInterval #Math.random #배열 #onclick #이벤트객체 #타이머 #웹게임 #HTML #CSS #웹개발 #티스토리
티스토리 태그 입력란 복사용
JavaScript, 알까기게임, 기억력게임, setInterval, clearInterval, Math.random, 배열, onclick, 이벤트객체, 타이머, 웹게임, HTML, CSS, 웹개발, 티스토리
반응형
'php' 카테고리의 다른 글
| Canvas 이미지·텍스트 완전 정리 (0) | 2026.07.15 |
|---|---|
| Canvas 드래그 그리기 완전 정리 (0) | 2026.07.15 |
| JavaScript document.write() — 문서에 직접 출력 완전 정리 (0) | 2026.07.15 |
| JavaScript innerHTML · this — 내용 교체와 이벤트 대상 완전 정리 (0) | 2026.07.15 |
| JavaScript document 객체 — location·URL·readyState 완전 정리 (0) | 2026.07.15 |
왕진 블로그

댓글