개요
현재 진행 중인 개인 프로젝트로, chrome dino를 모방하여 게임을 제작하고 있다. 이번 시간에는 아무 키나 누르는 순간 게임이 진행되는 현재 로직에서 특정 키를 눌렀을 때 게임이 시작되는 로직으로 변경하는 시간을 가져보자.
배경
내가 이 주제를 다루는 이유는 너무 간단하다. 나는 지금 아무 키나 눌렀을 때 게임을 시작하는 로직을 가지고 있다.
아무 키. 즉, 내가 'a'를 누르든 'space'를 누르든 심지어 'esc'를 눌러도 게임이 시작되어버린다는 의미다.
발단
개인 프로젝트 진행 중 웹 콘솔에 출력되는 로그를 살피기 위해 'F12'를 누르는 순간, 게임이 진행된다!?
이는 너무나 큰 불편이었다. 아직 게임을 진행하지 않고 로그만 살피고 싶은데 게임이 바로 진행되어버리니 살피고 싶은 로그가 후딱 지나가버리는 것이다...
전개
따라서 해당 코드를 수정할 필요가 있었다. 현재 코드에서 리스너를 이용해 게임을 시작하는 로직을 살펴보자.
window.addEventListener('keyup', reset, { once: true });
너무 단순하다... 아무 조건 없이 그냥 'keyup' 되었을 경우 게임이 시작된다.
우선적으로 나는 `reset` 함수를 바로 사용하지 않고 `startGame` 이라는 함수를 새롭게 만들어 그 안에서 `reset` 을 다루는 방식으로 수정했다. 물론 스페이스를 눌렀을 때만이다!!!
function startGame(event) {
// 스페이스 누를 경우만 게임 시작
if (waitingToStart || gameover) {
if (event.code === 'Space') {
reset();
}
}
}
window.addEventListener('keyup', startGame, { once: true });
위기
하지만 내 예상과는 달리 새로운 문제에 직면하게 되었다. 물론 위와 같이 수정하면 내 의도대로 `space` 에만 게임 시작이 작동하게 된다. 그러나 정확히 스페이스 바만 눌렀을 때만 작동한다. 즉, 다른 키를 누르다가 스페이스 바를 누르면 작동하지 않는다는 의미다.
우선적으로 이벤트 리스너에 대한 코드를 분석할 필요가 있다. 먼저 window, 현재 브라우저의 전역 객체를 나타내며, 브라우저에서 제공하는 모든 기능에 접근할 수 있게 해준다. addEventListener는 지정된 이벤트가 발생했을 때 실행할 함수를 등록하는 데 사용하는 메서드이다. 문자열 keyup 은 키보드에서 키가 눌렸다가 떨어지는 이벤트를 나타내고, startGame은 실행할 함수, 옵션 객체 { once: true } 는 이벤트 리스너의 동작 방식을 설정한다. 즉, `once: true` 는 이벤트 리스너가 한 번만 실행되도록 설정한다.
나는 내가 맞닥들인 문제가 `once: true` 에 있음을 확신했다. 스페이스 바가 아닌 다른 키를 눌렀을 때 startGame의 조건에 의해 reset은 실행되지 않는다. 하지만 `once: true` 때문에 다음으로 다른 키를 눌러도 keyup 이벤트에서 startGame이 다시 호출되지 않게 되는 것이다.
절정
그래서 나는 { once: true } 를 과감하게 지웠다. 그러니 바로 작동이 되어버렸다!!!
하지만 그대로 사용하게 되면 게임을 재시작할 때 딜레이 없이 바로 시작된다. 나는 이를 고칠 필요가 있다고 생각했다.
결말
우선적으로 `canRestart` 라는 변수를 선언하여 재시작 관련된 로직에 조건을 붙여주었다.
let canRestart = true;
function setupGameReset() {
if (!hasAddedEventListenersForRestart) {
hasAddedEventListenersForRestart = true;
setTimeout(() => {
canRestart = true;
window.addEventListener('keyup', startGame, { once: true });
}, 1000);
}
}
function startGame(event) {
// 스페이스 누를 경우만 게임 시작
if ((waitingToStart || gameover) && canRestart) {
if (event.code === 'Space') {
canRestart = false;
reset();
}
}
}
if (!gameover) {
window.addEventListener('keyup', startGame);
}
'Side Projects' 카테고리의 다른 글
Text-RPG(CLI) - 트러블슈팅 (1) | 2024.10.22 |
---|---|
모듈 시스템에서 변수 바인딩 방식 (0) | 2024.10.11 |
Prisma 다시 돌아보기 (2) | 2024.09.25 |
Session Storage / Local Storage (0) | 2024.09.23 |
gabia에서 ec2 인스턴스 도메인 설정하고 관리하기 (0) | 2024.09.20 |