반응형

HTML5의 <canvas> 태그는 간단한 게임을 개발하는 데 적합한 도구입니다. 픽셀 단위의 그래픽 작업과 JavaScript를 활용해 다양한 게임을 만들 수 있습니다. 이번 글에서는 캔버스를 활용해 간단한 공 튕기기 게임을 만드는 과정을 자세히 설명합니다.


1. 게임의 개요

1.1 게임 목표

플레이어는 화면 하단의 패들을 움직여 공이 화면 밖으로 떨어지지 않도록 막아야 합니다. 공이 화면 안에서 계속 튕기도록 하면서 점수를 얻는 방식입니다.


2. 프로젝트 구조

간단한 HTML, CSS, JavaScript 파일로 구성됩니다.

파일 구조

/game-project
  ├── index.html
  ├── style.css
  └── script.js

3. HTML 구조

HTML 파일에서 <canvas> 태그를 설정합니다.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Canvas 공 튕기기 게임</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>공 튕기기 게임</h1>
  <canvas id="gameCanvas" width="800" height="600"></canvas>
  <script src="script.js"></script>
</body>
</html>

4. CSS 스타일

CSS로 게임 화면의 디자인을 간단히 설정합니다.

/* style.css */
body {
  font-family: Arial, sans-serif;
  text-align: center;
  margin: 0;
  padding: 0;
  background-color: #f4f4f4;
}

h1 {
  margin-top: 20px;
  color: #333;
}

canvas {
  display: block;
  margin: 20px auto;
  border: 1px solid #000;
  background-color: #eee;
}

5. JavaScript 코드

게임의 핵심 로직은 JavaScript로 구현됩니다. 아래는 단계별로 코드를 설명합니다.

5.1 캔버스와 컨텍스트 설정

먼저, 캔버스와 2D 렌더링 컨텍스트를 가져옵니다.

// script.js
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

// 캔버스 크기
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;

5.2 게임 요소 정의

게임에 필요한 요소(공, 패들, 점수)를 정의합니다.

// 공 속성
const ball = {
  x: canvasWidth / 2,
  y: canvasHeight / 2,
  radius: 10,
  dx: 3, // x축 이동 속도
  dy: 3, // y축 이동 속도
};

// 패들 속성
const paddle = {
  width: 100,
  height: 10,
  x: canvasWidth / 2 - 50,
  y: canvasHeight - 30,
  speed: 5,
  dx: 0, // x축 이동 방향
};

// 점수
let score = 0;

5.3 공 그리기

공을 그리는 함수를 만듭니다.

function drawBall() {
  ctx.beginPath();
  ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
  ctx.fillStyle = 'blue';
  ctx.fill();
  ctx.closePath();
}

5.4 패들 그리기

패들을 그리는 함수를 정의합니다.

function drawPaddle() {
  ctx.beginPath();
  ctx.rect(paddle.x, paddle.y, paddle.width, paddle.height);
  ctx.fillStyle = 'green';
  ctx.fill();
  ctx.closePath();
}

5.5 점수 표시

점수를 캔버스 상단에 표시합니다.

function drawScore() {
  ctx.font = '16px Arial';
  ctx.fillStyle = 'black';
  ctx.fillText(`Score: ${score}`, 10, 20);
}

5.6 게임 업데이트

공의 위치를 업데이트하고 패들과 충돌 여부를 확인합니다.

function updateBallPosition() {
  ball.x += ball.dx;
  ball.y += ball.dy;

  // 좌우 벽 충돌
  if (ball.x + ball.radius > canvasWidth || ball.x - ball.radius < 0) {
    ball.dx *= -1;
  }

  // 상단 벽 충돌
  if (ball.y - ball.radius < 0) {
    ball.dy *= -1;
  }

  // 패들 충돌
  if (
    ball.y + ball.radius > paddle.y &&
    ball.x > paddle.x &&
    ball.x < paddle.x + paddle.width
  ) {
    ball.dy *= -1; // 공 방향 반전
    score += 1; // 점수 증가
  }

  // 바닥에 닿으면 게임 종료
  if (ball.y + ball.radius > canvasHeight) {
    alert('Game Over!');
    document.location.reload();
  }
}

5.7 패들 움직임 처리

키보드 입력을 통해 패들을 조작합니다.

document.addEventListener('keydown', (e) => {
  if (e.key === 'ArrowRight') paddle.dx = paddle.speed;
  if (e.key === 'ArrowLeft') paddle.dx = -paddle.speed;
});

document.addEventListener('keyup', (e) => {
  if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') paddle.dx = 0;
});

function updatePaddlePosition() {
  paddle.x += paddle.dx;

  // 패들이 캔버스 밖으로 나가지 않도록 제한
  if (paddle.x < 0) paddle.x = 0;
  if (paddle.x + paddle.width > canvasWidth) paddle.x = canvasWidth - paddle.width;
}

5.8 화면 그리기와 애니메이션

모든 요소를 그린 후 프레임을 갱신합니다.

function draw() {
  // 화면 초기화
  ctx.clearRect(0, 0, canvasWidth, canvasHeight);

  // 게임 요소 그리기
  drawBall();
  drawPaddle();
  drawScore();
}

function update() {
  updateBallPosition();
  updatePaddlePosition();
}

// 게임 루프 실행
function gameLoop() {
  draw();
  update();
  requestAnimationFrame(gameLoop);
}

gameLoop();

6. 게임 확장

6.1 난이도 조절

  • 공의 속도를 점점 증가시키거나 패들의 크기를 줄여 난이도를 높일 수 있습니다.

6.2 레벨 추가

  • 점수가 특정 값에 도달하면 새로운 레벨로 이동하거나 장애물을 추가하는 방식으로 확장할 수 있습니다.

7. 결론

이번 글에서는 HTML5 <canvas>를 활용해 간단한 공 튕기기 게임을 구현하는 방법을 단계별로 설명했습니다. 캔버스는 단순한 도형 그리기뿐 아니라, 인터랙티브한 콘텐츠와 게임 개발에서도 매우 유용한 도구입니다. 이 코드를 기반으로 더욱 창의적인 게임을 만들어보세요!

반응형

+ Recent posts