벽돌 깨기 게임

화면


 이번에는 JavaScript와 HTML5 Canvas를 사용하여 "벽돌깨기" 게임을 만들어 보겠습니다. 이 게임에서는 플레이어가 바닥의 패들을 좌우로 움직여 공을 튕겨내어 위에 있는 벽돌을 깨는 간단한 구조입니다.

1. 프로젝트 구조

flask_brick_breaker/ │ ├── app.py # Flask 서버 코드 ├── static/ │ └── game.js # JavaScript 파일 (게임 로직) └── templates/ └── index.html # HTML 파일 (게임 인터페이스)

2. Flask 서버 코드 (app.py)

from flask import Flask, render_template app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') if __name__ == '__main__': app.run(debug=True)

3. HTML 파일 (index.html)

index.html에서는 게임을 렌더링할 HTML5 canvas 요소를 추가합니다.

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Brick Breaker Game</title> <style> canvas { background: #f0f0f0; display: block; margin: 0 auto; border: 1px solid #000; } </style> </head> <body> <h1>Brick Breaker Game</h1> <canvas id="gameCanvas" width="480" height="320"></canvas> <script src="{{ url_for('static', filename='game.js') }}"></script> </body> </html>

4. 게임 로직 (JavaScript) - game.js

const canvas = document.getElementById("gameCanvas"); const ctx = canvas.getContext("2d"); let ballRadius = 10; let x = canvas.width / 2; let y = canvas.height - 30; let dx = 2; let dy = -2; let paddleHeight = 10; let paddleWidth = 75; let paddleX = (canvas.width - paddleWidth) / 2; let rightPressed = false; let leftPressed = false; let brickRowCount = 3; let brickColumnCount = 5; let brickWidth = 75; let brickHeight = 20; let brickPadding = 10; let brickOffsetTop = 30; let brickOffsetLeft = 30; let score = 0; // 벽돌 배열 생성 let bricks = []; for (let c = 0; c < brickColumnCount; c++) { bricks[c] = []; for (let r = 0; r < brickRowCount; r++) { bricks[c][r] = { x: 0, y: 0, status: 1 }; // status가 1일 때 벽돌이 남아있음 } } // 키보드 입력 처리 document.addEventListener("keydown", keyDownHandler); document.addEventListener("keyup", keyUpHandler); function keyDownHandler(e) { if (e.key == "Right" || e.key == "ArrowRight") { rightPressed = true; } else if (e.key == "Left" || e.key == "ArrowLeft") { leftPressed = true; } } function keyUpHandler(e) { if (e.key == "Right" || e.key == "ArrowRight") { rightPressed = false; } else if (e.key == "Left" || e.key == "ArrowLeft") { leftPressed = false; } } // 공 그리기 function drawBall() { ctx.beginPath(); ctx.arc(x, y, ballRadius, 0, Math.PI * 2); ctx.fillStyle = "#0095DD"; ctx.fill(); ctx.closePath(); } // 패들 그리기 function drawPaddle() { ctx.beginPath(); ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight); ctx.fillStyle = "#0095DD"; ctx.fill(); ctx.closePath(); } // 벽돌 그리기 function drawBricks() { for (let c = 0; c < brickColumnCount; c++) { for (let r = 0; r < brickRowCount; r++) { if (bricks[c][r].status == 1) { let brickX = c * (brickWidth + brickPadding) + brickOffsetLeft; let brickY = r * (brickHeight + brickPadding) + brickOffsetTop; bricks[c][r].x = brickX; bricks[c][r].y = brickY; ctx.beginPath(); ctx.rect(brickX, brickY, brickWidth, brickHeight); ctx.fillStyle = "#0095DD"; ctx.fill(); ctx.closePath(); } } } } // 공과 벽돌 충돌 처리 function collisionDetection() { for (let c = 0; c < brickColumnCount; c++) { for (let r = 0; r < brickRowCount; r++) { let b = bricks[c][r]; if (b.status == 1) { if (x > b.x && x < b.x + brickWidth && y > b.y && y < b.y + brickHeight) { dy = -dy; b.status = 0; score++; if (score == brickRowCount * brickColumnCount) { alert("YOU WIN, CONGRATULATIONS!"); document.location.reload(); } } } } } } // 점수 그리기 function drawScore() { ctx.font = "16px Arial"; ctx.fillStyle = "#0095DD"; ctx.fillText("Score: " + score, 8, 20); } // 게임 루프 function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); drawBricks(); drawBall(); drawPaddle(); drawScore(); collisionDetection(); // 공 벽 충돌 처리 if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) { dx = -dx; } if (y + dy < ballRadius) { dy = -dy; } else if (y + dy > canvas.height - ballRadius) { if (x > paddleX && x < paddleX + paddleWidth) { dy = -dy; } else { alert("GAME OVER"); document.location.reload(); } } // 패들 이동 처리 if (rightPressed && paddleX < canvas.width - paddleWidth) { paddleX += 7; } else if (leftPressed && paddleX > 0) { paddleX -= 7; } // 공 이동 x += dx; y += dy; requestAnimationFrame(draw); } draw();

5. 게임 실행

이제 app.py 파일을 실행하여 Flask 서버를 실행합니다.

python app.py

브라우저에서 http://127.0.0.1:5000/에 접속하면 벽돌깨기 게임이 실행됩니다.

게임 동작 설명

  • 이 화면에서 튕기면서 벽돌을 맞추고, 패들을 움직여 공을 놓치지 않도록 합니다.
  • 화살표 키(, )를 사용하여 패들을 좌우로 움직일 수 있습니다.
  • 공이 화면 아래쪽으로 떨어지면 게임이 종료되고, 점수를 올리며 모든 벽돌을 깨면 승리합니다.

6. 요약

이 예제에서는 Flask를 사용하여 간단한 웹 기반 벽돌깨기 게임을 만들었습니다. 주요 구성 요소는 다음과 같습니다:

  • Flask를 통해 웹 서버를 호스팅하고 HTML과 JavaScript를 서빙.
  • HTML5 Canvas를 사용하여 게임 그래픽을 그리기.
  • JavaScript를 사용하여 공의 이동, 패들 조작, 벽돌 충돌 등의 게임 로직을 처리.

댓글 쓰기

댓글 목록