본문 바로가기

[Pygame] 🧱 벽돌 깨기 게임 만들기 9강 | 점수 & 라이프 시스템

@도마22026. 2. 24. 19:00
728x90


점수 & 라이프 시스템

이번 강의에서는 벽돌깨기 게임에
점수(Score)라이프(Life) 시스템을 추가합니다.

또한 공을 놓쳤을 때
게임을 완전히 처음 상태로 리셋하는 구조를 구현합니다.

이번 강의의 목표는 다음과 같습니다.

  • 벽돌을 제거하면 점수가 증가하도록 만듭니다
  • 공을 놓치면 라이프가 감소하도록 만듭니다
  • 라이프가 남아 있더라도 게임은 완전히 리셋됩니다
  • 라이프가 0이 되면 게임 오버 상태가 됩니다

점수와 라이프가 필요한 이유

현재 게임은 벽돌을 모두 제거해도
“얼마나 잘했는지”를 판단할 기준이 없습니다.

점수와 라이프는 다음 역할을 합니다.

  • 점수는 플레이 성과를 보여줍니다
  • 라이프는 실수를 허용하는 범위입니다
  • 게임의 성공과 실패 조건을 명확히 합니다

이제부터 게임은
시작 → 진행 → 실패 → 재시작이라는 구조를 가지게 됩니다.


점수와 라이프 변수 추가

먼저 점수와 라이프 변수를 선언합니다.

score = 0
lives = 3

 

  • score 는 벽돌을 깰 때마다 증가합니다
  • lives 는 공을 놓칠 때마다 감소합니다

 


텍스트 출력 준비하기

점수와 라이프를 화면에 표시하기 위해
폰트 객체를 생성합니다.

font = pygame.font.SysFont(None, 30)

점수와 라이프 화면에 표시하기

매 프레임마다 점수와 라이프를 화면에 그립니다.

score_text = font.render(f"Score: {score}", True, WHITE)
life_text = font.render(f"Lives: {lives}", True, WHITE)

screen.blit(score_text, (10, 10))
screen.blit(life_text, (SCREEN_WIDTH - 100, 10))

이제 플레이어는
현재 상태를 항상 확인할 수 있습니다.


벽돌 제거 시 점수 증가

7강에서 구현한 벽돌 충돌 코드에
점수 증가 처리를 추가합니다.

score += 10

벽돌 하나당 10점을 부여합니다.
점수 값은 이후 언제든 조정할 수 있습니다.


공을 놓쳤을 때 처리

공이 화면 아래로 떨어지면
라이프를 감소시키고 게임을 리셋합니다.

if ball_rect.top > SCREEN_HEIGHT:
    lives -= 1

이제 라이프가 남아 있는지 확인합니다.


게임 완전 리셋 처리

라이프가 남아 있다면
게임을 완전히 초기 상태로 되돌립니다.

if lives > 0:
    ball_x = SCREEN_WIDTH // 2
    ball_y = SCREEN_HEIGHT // 2
    ball_speed_x = 5
    ball_speed_y = -5

    paddle_rect.x = (SCREEN_WIDTH - paddle_width) // 2

    bricks.clear()
    for row in range(rows):
        for col in range(cols):
            brick_x = col * (brick_width + brick_padding) + 35
            brick_y = row * (brick_height + brick_padding) + 50
            bricks.append(
                pygame.Rect(brick_x, brick_y, brick_width, brick_height)
            )

이 구조는
게임을 처음 실행한 상태와 완전히 동일한 상태를 만듭니다.


라이프가 0일 때 게임 오버

라이프가 0이 되면
게임을 종료합니다.

if lives <= 0:
    running = False

게임 오버 화면은
후반부 디자인 강의에서 다룹니다.


현재 단계의 결과

이번 강의까지 구현된 결과는 다음과 같습니다.

  • 벽돌을 제거하면 점수가 증가합니다
  • 공을 놓치면 라이프가 감소합니다
  • 라이프가 남아 있어도 게임은 처음부터 다시 시작됩니다
  • 라이프가 0이 되면 게임이 종료됩니다

이제 벽돌깨기 게임은
명확한 실패 조건을 가진 완전한 게임 구조가 되었습니다.

다음 강의에서는
아이템을 추가하여 게임 진행에 변화를 줍니다.



전체 코드

더보기
import pygame
import sys

pygame.init()

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Breakout Game")

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

clock = pygame.time.Clock()
FPS = 60

font = pygame.font.SysFont(None, 30)

score = 0
lives = 3

paddle_width = 100
paddle_height = 15
paddle_speed = 7

paddle_rect = pygame.Rect(
    (SCREEN_WIDTH - paddle_width) // 2,
    SCREEN_HEIGHT - 40,
    paddle_width,
    paddle_height
)

ball_radius = 8
ball_x = SCREEN_WIDTH // 2
ball_y = SCREEN_HEIGHT // 2
ball_speed_x = 5
ball_speed_y = -5

ball_rect = pygame.Rect(
    ball_x - ball_radius,
    ball_y - ball_radius,
    ball_radius * 2,
    ball_radius * 2
)

brick_width = 60
brick_height = 20
brick_padding = 10
rows = 4
cols = 10

bricks = []

def create_bricks():
    bricks.clear()
    for row in range(rows):
        for col in range(cols):
            brick_x = col * (brick_width + brick_padding) + 35
            brick_y = row * (brick_height + brick_padding) + 50
            bricks.append(
                pygame.Rect(brick_x, brick_y, brick_width, brick_height)
            )

create_bricks()

running = True
while running:
    clock.tick(FPS)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        paddle_rect.x -= paddle_speed
    if keys[pygame.K_RIGHT]:
        paddle_rect.x += paddle_speed

    paddle_rect.left = max(paddle_rect.left, 0)
    paddle_rect.right = min(paddle_rect.right, SCREEN_WIDTH)

    ball_x += ball_speed_x
    ball_y += ball_speed_y

    ball_rect.x = ball_x - ball_radius
    ball_rect.y = ball_y - ball_radius

    if ball_rect.left <= 0 or ball_rect.right >= SCREEN_WIDTH:
        ball_speed_x *= -1
    if ball_rect.top <= 0:
        ball_speed_y *= -1

    if ball_rect.colliderect(paddle_rect):
        ball_speed_y *= -1
        ball_rect.bottom = paddle_rect.top
        ball_y = ball_rect.centery

    for brick in bricks:
        if ball_rect.colliderect(brick):
            overlap_left = ball_rect.right - brick.left
            overlap_right = brick.right - ball_rect.left
            overlap_top = ball_rect.bottom - brick.top
            overlap_bottom = brick.bottom - ball_rect.top

            min_overlap = min(overlap_left, overlap_right, overlap_top, overlap_bottom)

            if min_overlap == overlap_left or min_overlap == overlap_right:
                ball_speed_x *= -1
            else:
                ball_speed_y *= -1

            bricks.remove(brick)
            score += 10
            break

    if ball_rect.top > SCREEN_HEIGHT:
        lives -= 1
        if lives <= 0:
            running = False
        else:
            ball_x = SCREEN_WIDTH // 2
            ball_y = SCREEN_HEIGHT // 2
            ball_speed_x = 5
            ball_speed_y = -5
            paddle_rect.x = (SCREEN_WIDTH - paddle_width) // 2
            create_bricks()

    screen.fill(BLACK)

    score_text = font.render(f"Score: {score}", True, WHITE)
    life_text = font.render(f"Lives: {lives}", True, WHITE)
    screen.blit(score_text, (10, 10))
    screen.blit(life_text, (SCREEN_WIDTH - 100, 10))

    pygame.draw.rect(screen, WHITE, paddle_rect)
    pygame.draw.circle(screen, WHITE, (ball_x, ball_y), ball_radius)

    for brick in bricks:
        pygame.draw.rect(screen, WHITE, brick)

    pygame.display.flip()

pygame.quit()
sys.exit()

728x90
도마2
@도마2 :: 도마의 코드노트

초보자를 위한 코딩 강의를 정리합니다. 파이썬부터 C#, Unity 게임 제작까지 차근차근 기록합니다. — 도마

목차