DH의 개발 공부로그
[TypeScript] JavaScript 슈팅게임에 TypeScript 적용하기! #7 - 마무리 본문
728x90
Key Event
키이벤트는 원래 keyEvent
함수 안에서 onKeyUp
과 onKeyDown
을 한번에 해주었는데,
게임이 끝나고 초기화를 해줄 때 키이벤트를 삭제해주기 위해서 세분화 했습니다.onKeyUp
과 onKeyDown
은 event
인자를 받는데 그 타입은 KeyboardEvent
로 지정을 해주었습니다.
private keyEvent(): void {
if (!gameOver) {
document.addEventListener("keydown", this.onKeyDown);
document.addEventListener("keyup", this.onKeyUp);
}
}
private onKeyUp = (event: KeyboardEvent): void => {
if (event.code === "Space") {
this.createBullet(); // 총알 생성
}
delete keysDown[event.key];
}
private onKeyDown = (event: KeyboardEvent): void => {
keysDown[event.key] = true;
}
총알 & 운석 생성
총알과 운석 생성 함수에서는 Type Narrowing
을 이용해서 쉽게 오류를 해결했습니다.
private createBullet(): void {
const { spaceShip } = this;
let b = new Bullet();
if (spaceShip instanceof SpaceShip) {
b.init(spaceShip);
}
}
private createMeteor(): void {
interval = setInterval(() => {
let meteor = new Meteor();
meteor.init(this.canvas.width);
}, 1000);
}
update() & quit()
update()
도 마찬가지로 Type Narrowing
을 이용해서 쉽고, 간단하게 변환을 하였습니다.
게임이 종료되면 실행이 될 quit()
은 다음과 같이 초기화 해주었습니다.
private update(): void {
const { spaceShip } = this;
if (spaceShip instanceof SpaceShip) {
if ("ArrowRight" in keysDown) {
spaceShip.x += 4;
// right
};
if ("ArrowLeft" in keysDown) {
spaceShip.x -= 4;
// left
};
if ("ArrowUp" in keysDown) {
spaceShip.y -= 4;
// right
};
if ("ArrowDown" in keysDown) {
spaceShip.y += 4;
// left
};
if (spaceShip.x <= 0) {
spaceShip.x = 0;
} else if (spaceShip.x >= this.canvas.width - 57) {
spaceShip.x = this.canvas.width - 57;
};
if (spaceShip.y <= 0) {
spaceShip.y = 0;
} else if (spaceShip.y >= this.canvas.height - 65) {
spaceShip.y = this.canvas.height - 65;
};
}
for (let i = 0; i < bulletList.length; i++) {
if (bulletList[i].alive) {
bulletList[i].update();
bulletList[i].checkHit();
} else {
bulletList.splice(i, 1);
};
};
for (let i = 0; i < meteorList.length; i++) {
if (spaceShip instanceof SpaceShip) {
meteorList[i].update(spaceShip, this.canvas.height);
}
};
if (spaceShip instanceof SpaceShip) {
// 레벨 체크
spaceShip.update();
}
}
private quit(): void {
clearInterval(interval);
game = null;
this.spaceShip = null;
document.removeEventListener("keydown", this.onKeyDown);
document.removeEventListener("keyup", this.onKeyUp);
score = 0;
bulletList = [];
meteorList = [];
gameOver = false;
keysDown = {}
}
addEventListener()
마지막으로 게임을 실행하고, 게임설명서를 보기 위한 버튼에 addEventListener
에는Optional Chaining
문법을 이용해서 작업을 하였습니다.
아래의 코드들은 Game
클래스에 속해있는 것이 아니며, 조건문으로 감싸기 보다는,Optional Chaining
을 이용해서 원하는 DOM객체에 접근했을 때 undefined
또는 null
이
아닌 경우에 실행 하는 것이 좋은 코드라고 생각하여 다음과 같이 작업을 했습니다.
$gameBtn?.addEventListener("click", () => {
game = new Game();
});
$manualBtn?.addEventListener('click', () => {
if ($manualScreen instanceof HTMLDivElement) {
$manualScreen.classList.add('on');
}
})
$okBtn?.addEventListener('click', () => {
if ($manualScreen instanceof HTMLDivElement) {
$manualScreen.classList.remove('on');
}
})
728x90
'TypeScript' 카테고리의 다른 글
[TypeScript] React.FC에 사용에 대해 생각해보기 (0) | 2023.03.30 |
---|---|
[Vite, TypeScript] Vite + 타입스크립트 환경에서 절대 경로 설정하기! (0) | 2023.03.21 |
[TypeScript] JavaScript 슈팅게임에 TypeScript 적용하기! #6 - Bullet & Meteor (0) | 2023.02.27 |
[TypeScript] JavaScript 슈팅게임에 TypeScript 적용하기! #5 - DOM 조작에 대한 Type Narrowing (0) | 2023.02.25 |
[TypeScript] JavaScript 슈팅게임에 TypeScript 적용하기! #4 - 이미지 부분 변환하기! (0) | 2023.02.24 |
Comments