본문 바로가기
JavaScript

[JavaScript] 비행기 슈팅 게임 만들기 - (3) 총알 발사하기

by teamnova 2024. 9. 28.
728x90

안녕하세요.

오늘은 지난 시간에 이어서, 비행기 슈팅게임에서 총알을 발사하는 기능을 구현하겠습니다.

총알은 플레이어가 스페이스바 키를 누르면 비행기에서 발사되며, 시간이 지날수록 화면 위쪽으로 이동해야 합니다.

 

 

 

이전 코드는 아래 링크를 통해 확인할 수 있습니다.

2024.09.15 - [JavaScript] - [JavaScript] 비행기 슈팅 게임 만들기 - (2) 적 생성하기

 

 

1. 총알 배열 설정

  • 다수의 총알을 관리하기 위해 bullets 배열을 설정합니다.
const bullets = []; // 총알을 담을 배열

 

2. 총알 발사 함수 작성

 

  • 비행기 중앙에서 총알을 발사하며, plane.x 위치를 기준으로 총알이 나갑니다.
  • bullets 배열에 총알 객체를 추가합니다.
// 총알을 발사하는 함수
function shootBullet() {
    const bullet = {
        x: plane.x + plane.width / 2 - 5, // 비행기 중앙에서 발사
        y: plane.y, // 비행기 위치에서 발사
        width: 5, // 총알 너비
        height: 10, // 총알 높이
        speed: 7, // 총알 속도
    };
    bullets.push(bullet); // 총알 배열에 추가
}

 

 

3. 총알 그리기 함수 작성

 

  • fillRect()를 이용해 총알을 그립니다. 총알은 노란색으로 표시하겠습니다.
  • forEach()를 사용해 배열 안의 각 총알을 그립니다.
// 총알을 그리는 함수
function drawBullets() {
    bullets.forEach((bullet) => {
        ctx.fillStyle = 'yellow'; // 총알 색상 설정
        ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height); // 총알 그리기
    });
}

 

 

4. 총알 위치를 업데이트 하는 함수 작성

 

  • 총알이 위로 이동하도록 bullet.y 값을 감소시킵니다.
  • 총알이 화면 위로 벗어나면 배열에서 제거됩니다.
// 총알의 위치를 업데이트하는 함수
function updateBullets() {
    bullets.forEach((bullet, index) => {
        bullet.y -= bullet.speed; // 총알이 위로 올라감

        // 총알이 화면을 벗어나면 배열에서 제거
        if (bullet.y < 0) {
            bullets.splice(index, 1); // 총알 제거
        }
    });
}

 

 

5. 키보드 입력에 따라 총알 발사 이벤트 처리

  • keydown 이벤트를 사용하여 사용자가 스페이스바를 누를 때 총알이 발사되도록 설정합니다.
// 키보드 입력 처리: 키를 눌렀을 때
window.addEventListener('keydown', function(e) {
    if (e.code === 'ArrowLeft') { // 왼쪽 화살표 키가 눌렸을 때
        plane.moveLeft = true; // 왼쪽 이동을 시작
    }
    if (e.code === 'ArrowRight') { // 오른쪽 화살표 키가 눌렸을 때
        plane.moveRight = true; // 오른쪽 이동을 시작
    }
    if (e.code === 'Space') { // 스페이스바를 누르면 총알 발사
        shootBullet(); // 총알 발사 함수 호출
    }
});

 

6. 게임 루프 업데이트

// 게임 루프 함수: 게임의 각 프레임을 업데이트하고 렌더링하는 함수
function gameLoop() {
    ctx.clearRect(0, 0, canvas.width, canvas.height); // 캔버스 전체를 지워서 이전 프레임의 그림을 지움
    drawPlane(); // 비행기 그리기
    update(); // 비행기 위치 업데이트

    drawEnemies(); // 적 그리기
    updateEnemies(); // 적 위치 업데이트

    drawBullets(); // 총알 그리기
    updateBullets(); // 총알 위치 업데이트

    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; // 오른쪽 이동을 멈춤
    }
});

// 게임 루프 함수: 게임의 각 프레임을 업데이트하고 렌더링하는 함수
function gameLoop() {
    ctx.clearRect(0, 0, canvas.width, canvas.height); // 캔버스 전체를 지워서 이전 프레임의 그림을 지움
    drawPlane(); // 비행기 그리기
    update(); // 비행기 위치 업데이트

    drawEnemies(); // 적 그리기
    updateEnemies(); // 적 위치 업데이트

    drawBullets(); // 총알 그리기
    updateBullets(); // 총알 위치 업데이트

    requestAnimationFrame(gameLoop); // 다음 프레임 호출
}

gameLoop(); // 게임 시작