728x90
안녕하세요.
오늘은 지난 시간에 이어서, 적과 총알이 충돌하면 적을 제거하고, 적과 비행기가 충돌하면 게임 오버가 되는 기능을 구현하겠습니다.
이전 코드는 다음 링크를 통해 확인할 수 있습니다.
2024.09.15 - [JavaScript] - [JavaScript] 비행기 슈팅 게임 만들기 - (3) 총알 발사하기
1. 게임 오버 상태 변수 설정
- isGameOver 변수를 추가하여 게임이 종료되었는지 여부를 추적합니다. 초기값은 false로 설정됩니다.
let isGameOver = false; // 게임 오버 상태를 추적할 변수
2. 충돌 감지 함수 작성
- 두 개의 객체가 충돌하는지 확인하는 함수입니다. 이 함수는 총알과 적, 적과 비행기의 충돌을 처리할 수 있습니다.
- obj1과 obj2는 충돌을 검사할 두 개의 객체(총알, 적, 비행기 등)를 의미하며, 각각의 위치와 크기를 비교해 충돌 여부를 반환합니다.
// 충돌 감지 함수 (총알과 적의 충돌, 적과 비행기의 충돌을 처리)
function checkCollision(obj1, obj2) {
// 두 객체가 겹쳤는지 여부를 반환
return (
obj1.x < obj2.x + obj2.width && // obj1의 오른쪽 경계가 obj2의 왼쪽 경계를 넘지 않음
obj1.x + obj1.width > obj2.x && // obj1의 왼쪽 경계가 obj2의 오른쪽 경계를 넘음
obj1.y < obj2.y + obj2.height && // obj1의 아래쪽 경계가 obj2의 위쪽 경계를 넘지 않음
obj1.y + obj1.height > obj2.y // obj1의 위쪽 경계가 obj2의 아래쪽 경계를 넘음
);
}
3. 충돌 처리 함수 작성
- bullets 배열의 각 총알과 enemies 배열의 각 적에 대해 충돌을 확인하고, 충돌 시 총알과 적을 배열에서 제거합니다.
- 또한 적과 비행기가 충돌하면 isGameOver를 true로 설정하여 게임 오버 상태로 만듭니다.
// 적과 총알 및 비행기의 충돌을 확인하고 처리하는 함수
function handleCollisions() {
bullets.forEach((bullet, bulletIndex) => {
enemies.forEach((enemy, enemyIndex) => {
// 총알과 적의 충돌 처리
if (checkCollision(bullet, enemy)) {
// 충돌 시 적과 총알을 배열에서 제거
bullets.splice(bulletIndex, 1); // 총알 제거
enemies.splice(enemyIndex, 1); // 적 제거
}
});
});
enemies.forEach((enemy) => {
// 적과 비행기의 충돌 처리
if (checkCollision(enemy, plane)) {
isGameOver = true; // 게임 오버 설정
}
});
}
4. 게임 오버 처리 함수 작성
- 게임이 종료되면 화면에 "Game Over" 메시지를 표시하는 함수입니다. ctx.fillText()를 사용해 캔버스 중앙에 게임 오버 메시지를 출력합니다.
// 게임 오버를 처리하는 함수
function gameOver() {
ctx.fillStyle = 'red'; // 게임 오버 메시지 색상 설정
ctx.font = '48px Arial'; // 폰트 설정
ctx.fillText('Game Over', canvas.width / 2 - 120, canvas.height / 2); // 화면에 메시지 표시
}
5. 게임 루프 수정
- 게임 루프에서 isGameOver가 true일 경우, 게임을 중단하고 gameOver() 함수를 호출해 게임 오버 메시지를 표시합니다. 그렇지 않으면 계속해서 게임을 진행합니다.
// 게임 루프 함수: 게임의 각 프레임을 업데이트하고 렌더링하는 함수
function gameLoop() {
if (isGameOver) {
gameOver(); // 게임 오버 시 메시지 표시
return; // 더 이상 게임을 진행하지 않음
}
ctx.clearRect(0, 0, canvas.width, canvas.height); // 캔버스 전체를 지워서 이전 프레임의 그림을 지움
drawPlane(); // 비행기 그리기
update(); // 비행기 위치 업데이트
drawEnemies(); // 적 그리기
updateEnemies(); // 적 위치 업데이트
drawBullets(); // 총알 그리기
updateBullets(); // 총알 위치 업데이트
handleCollisions(); // 충돌 감지 및 처리
requestAnimationFrame(gameLoop); // 다음 프레임 호출
}
현재까지 전체 코드
const canvas = document.getElementById('gameCanvas'); // HTML에서 캔버스를 가져옵니다.
const ctx = canvas.getContext('2d'); // 캔버스에서 2D 그리기 기능을 사용할 수 있게 합니다.
canvas.width = 400; // 캔버스의 너비를 400px로 설정
canvas.height = 600; // 캔버스의 높이를 600px로 설정
// 비행기 객체 설정
const plane = {
x: canvas.width / 2 - 20, // 비행기의 초기 x 위치를 캔버스 중앙에 설정
y: canvas.height - 60, // 비행기의 초기 y 위치를 캔버스 하단에 설정
width: 40, // 비행기의 너비
height: 40, // 비행기의 높이
speed: 5, // 비행기의 이동 속도
moveLeft: false, // 왼쪽으로 이동 중인지 여부
moveRight: false, // 오른쪽으로 이동 중인지 여부
};
// 비행기 그리기 함수
function drawPlane() {
ctx.fillStyle = 'white'; // 비행기의 색상을 흰색으로 설정
ctx.fillRect(plane.x, plane.y, plane.width, plane.height); // 비행기를 직사각형으로 그립니다.
}
// 비행기 위치 업데이트 함수
function update() {
if (plane.moveLeft && plane.x > 0) { // 왼쪽으로 이동 중이고 캔버스를 벗어나지 않았을 때
plane.x -= plane.speed; // 왼쪽으로 이동
}
if (plane.moveRight && plane.x + plane.width < canvas.width) { // 오른쪽으로 이동 중이고 캔버스를 벗어나지 않았을 때
plane.x += plane.speed; // 오른쪽으로 이동
}
}
const enemies = []; // 적 배열을 선언하여 다수의 적을 관리
// 적 객체를 생성하는 함수
function createEnemy() {
const enemy = {
x: Math.random() * (canvas.width - 40), // 적의 X 위치를 랜덤으로 설정
y: 0, // 적의 초기 Y 위치는 화면 위
width: 40, // 적의 너비
height: 40, // 적의 높이
speed: 2, // 적이 내려오는 속도
};
enemies.push(enemy); // 적을 배열에 추가
}
// 적을 그리는 함수
function drawEnemies() {
enemies.forEach((enemy) => {
ctx.fillStyle = 'red'; // 적의 색상을 빨간색으로 설정
ctx.fillRect(enemy.x, enemy.y, enemy.width, enemy.height); // 적을 그립니다.
});
}
// 적의 위치를 업데이트하는 함수
function updateEnemies() {
enemies.forEach((enemy, index) => {
enemy.y += enemy.speed; // 적이 아래로 이동
// 적이 화면 아래로 나가면 배열에서 제거
if (enemy.y > canvas.height) {
enemies.splice(index, 1); // 적 제거
}
});
}
const bullets = []; // 비행기에서 발사할 총알을 담을 배열
// 총알을 발사하는 함수
function shootBullet() {
const bullet = {
x: plane.x + plane.width / 2 - 5, // 비행기 중앙에서 발사
y: plane.y, // 비행기 위치에서 발사
width: 5, // 총알 너비
height: 10, // 총알 높이
speed: 7, // 총알 속도
};
bullets.push(bullet); // 총알 배열에 추가
}
// 총알을 그리는 함수
function drawBullets() {
bullets.forEach((bullet) => {
ctx.fillStyle = 'yellow'; // 총알 색상 설정
ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height); // 총알 그리기
});
}
// 총알의 위치를 업데이트하는 함수
function updateBullets() {
bullets.forEach((bullet, index) => {
bullet.y -= bullet.speed; // 총알이 위로 올라감
// 총알이 화면을 벗어나면 배열에서 제거
if (bullet.y < 0) {
bullets.splice(index, 1); // 총알 제거
}
});
}
// 일정 시간마다 적이 생성되도록 설정 (적이 계속 등장)
setInterval(createEnemy, 1000); // 1초마다 적을 생성
// 키보드 입력 처리: 키를 눌렀을 때
window.addEventListener('keydown', function(e) {
if (e.code === 'ArrowLeft') { // 왼쪽 화살표 키가 눌렸을 때
plane.moveLeft = true; // 왼쪽 이동을 시작
}
if (e.code === 'ArrowRight') { // 오른쪽 화살표 키가 눌렸을 때
plane.moveRight = true; // 오른쪽 이동을 시작
}
if (e.code === 'Space') { // 스페이스바를 누르면 총알 발사
shootBullet(); // 총알 발사 함수 호출
}
});
// 키보드 입력 처리: 키를 뗐을 때
window.addEventListener('keyup', function(e) {
if (e.code === 'ArrowLeft') { // 왼쪽 화살표 키를 뗐을 때
plane.moveLeft = false; // 왼쪽 이동을 멈춤
}
if (e.code === 'ArrowRight') { // 오른쪽 화살표 키를 뗐을 때
plane.moveRight = false; // 오른쪽 이동을 멈춤
}
});
let isGameOver = false; // 게임 오버 상태를 추적할 변수
// 충돌 감지 함수 (총알과 적의 충돌, 적과 비행기의 충돌을 처리)
function checkCollision(obj1, obj2) {
// 두 객체가 겹쳤는지 여부를 반환
return (
obj1.x < obj2.x + obj2.width && // obj1의 오른쪽 경계가 obj2의 왼쪽 경계를 넘지 않음
obj1.x + obj1.width > obj2.x && // obj1의 왼쪽 경계가 obj2의 오른쪽 경계를 넘음
obj1.y < obj2.y + obj2.height && // obj1의 아래쪽 경계가 obj2의 위쪽 경계를 넘지 않음
obj1.y + obj1.height > obj2.y // obj1의 위쪽 경계가 obj2의 아래쪽 경계를 넘음
);
}
// 적과 총알 및 비행기의 충돌을 확인하고 처리하는 함수
function handleCollisions() {
bullets.forEach((bullet, bulletIndex) => {
enemies.forEach((enemy, enemyIndex) => {
// 총알과 적의 충돌 처리
if (checkCollision(bullet, enemy)) {
// 충돌 시 적과 총알을 배열에서 제거
bullets.splice(bulletIndex, 1); // 총알 제거
enemies.splice(enemyIndex, 1); // 적 제거
}
});
});
enemies.forEach((enemy) => {
// 적과 비행기의 충돌 처리
if (checkCollision(enemy, plane)) {
isGameOver = true; // 게임 오버 설정
}
});
}
// 게임 오버를 처리하는 함수
function gameOver() {
ctx.fillStyle = 'red'; // 게임 오버 메시지 색상 설정
ctx.font = '48px Arial'; // 폰트 설정
ctx.fillText('Game Over', canvas.width / 2 - 120, canvas.height / 2); // 화면에 메시지 표시
}
// 게임 루프 함수: 게임의 각 프레임을 업데이트하고 렌더링하는 함수
function gameLoop() {
if (isGameOver) {
gameOver(); // 게임 오버 시 메시지 표시
return; // 더 이상 게임을 진행하지 않음
}
ctx.clearRect(0, 0, canvas.width, canvas.height); // 캔버스 전체를 지워서 이전 프레임의 그림을 지움
drawPlane(); // 비행기 그리기
update(); // 비행기 위치 업데이트
drawEnemies(); // 적 그리기
updateEnemies(); // 적 위치 업데이트
drawBullets(); // 총알 그리기
updateBullets(); // 총알 위치 업데이트
handleCollisions(); // 충돌 감지 및 처리
requestAnimationFrame(gameLoop); // 다음 프레임 호출
}
gameLoop(); // 게임 시작
'JavaScript' 카테고리의 다른 글
[JavaScript] 스네이크 게임 만들기 (4) | 2024.10.19 |
---|---|
[JavaScript] 비행기 슈팅 게임 만들기 - (5) 점수, 목숨, 다시 시작 구현 (2) | 2024.10.10 |
[JavaScript] 비행기 슈팅 게임 만들기 - (3) 총알 발사하기 (2) | 2024.09.28 |
[JavaScript] 비행기 슈팅 게임 만들기 - (2) 적 생성하기 (2) | 2024.09.21 |
[JavaScript] 비행기 슈팅 게임 만들기 - (1) 비행기 그리기 (3) | 2024.09.15 |