728x90

게임 시작 흐름 개선
이번 강의에서는 게임의 구조를 바꾸지 않고
플레이 감각을 조정하는 밸런스 패치를 진행합니다.
이번 강의의 핵심은 다음 두 가지입니다.
- 게임 시작 시 공이 바로 움직이지 않도록 수정합니다
- 아이템 낙하 속도를 느리게 조절합니다
이 작업을 통해
게임이 훨씬 친절하고 안정적인 플레이 흐름을 가지게 됩니다.
왜 밸런스 패치가 필요한가
현재 상태의 게임은 다음과 같은 특징이 있습니다.
- 게임이 시작되자마자 공이 움직입니다
- 실수하면 바로 반응해야 해서 초보자에게 부담이 됩니다
- 아이템이 빠르게 떨어져 체감 난이도가 높습니다
이 강의에서는
“준비 → 시작 → 진행” 구조를 명확히 만들어
게임의 완성도를 한 단계 끌어올립니다.
공 대기 상태 개념 추가
공이 움직이기 전 상태를
ball_active 라는 변수로 관리합니다.
ball_active = False
- False : 공이 패들 위에 고정된 상태
- True : 공이 실제로 이동하는 상태
공을 패들 위에 고정하기
공이 활성화되지 않았을 때는
공의 위치를 패들 위로 고정합니다.
if not ball_active:
ball_x = paddle_rect.centerx
ball_y = paddle_rect.top - ball_radius
이렇게 하면
패들을 움직일 때 공도 함께 움직이게 됩니다.
스페이스 키로 공 발사하기
공이 대기 상태일 때
스페이스 키를 누르면 공이 움직이도록 합니다.
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and game_state == "PLAY":
ball_active = True
이제 플레이어는
준비가 되었을 때 직접 게임을 시작할 수 있습니다.
공 이동 처리 조건 분리
공 이동 코드는
ball_active 가 True 일 때만 실행되도록 수정합니다.
if ball_active:
ball_x += ball_speed_x
ball_y += ball_speed_y
이로 인해
대기 상태에서는 공이 절대 움직이지 않습니다.
공 리셋 시 다시 대기 상태로 만들기
공을 놓쳤을 때도
다시 대기 상태로 돌아가야 합니다.
ball_active = False
이 코드는
라이프가 감소한 직후에 적용합니다.
아이템 낙하 속도 조정
기존 아이템 낙하 속도는
게임 진행 속도에 비해 다소 빠른 편이었습니다.
item_speed = 2
이제 아이템은
조금 더 천천히 떨어지며
플레이어가 반응할 시간을 제공합니다.
현재 단계의 결과
이번 강의까지 적용된 변화는 다음과 같습니다.
- 게임 시작 시 공이 패들 위에서 대기합니다
- 스페이스 키를 눌러야 공이 발사됩니다
- 아이템을 더 안정적으로 획득할 수 있습니다
이제 게임은
초보자에게도 친절한 구조가 되었습니다.

전체 코드
더보기
import pygame
import sys
import random
pygame.init()
pygame.mixer.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)
GREEN = (0, 200, 0)
EFFECT_COLOR = (255, 200, 200)
clock = pygame.time.Clock()
FPS = 60
font = pygame.font.SysFont(None, 30)
title_font = pygame.font.SysFont(None, 64)
info_font = pygame.font.SysFont(None, 28)
brick_sound = pygame.mixer.Sound("brick.wav")
paddle_sound = pygame.mixer.Sound("paddle.wav")
item_sound = pygame.mixer.Sound("item.wav")
game_state = "TITLE"
ball_active = False
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 = paddle_rect.centerx
ball_y = paddle_rect.top - ball_radius
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 = []
items = []
effects = []
item_speed = 2
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)
)
def create_item(x, y):
items.append(pygame.Rect(x, y, 20, 20))
create_bricks()
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
if game_state == "TITLE":
game_state = "PLAY"
elif game_state == "PLAY" and not ball_active:
ball_active = True
if game_state == "TITLE":
screen.fill(BLACK)
screen.blit(
title_font.render("BREAKOUT GAME", True, WHITE),
(SCREEN_WIDTH // 2 - 200, 200)
)
screen.blit(
info_font.render("Press SPACE to Start", True, WHITE),
(SCREEN_WIDTH // 2 - 110, 300)
)
pygame.display.flip()
continue
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)
if not ball_active:
ball_x = paddle_rect.centerx
ball_y = paddle_rect.top - ball_radius
else:
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_active:
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
paddle_sound.play()
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
if random.random() < 0.3:
create_item(brick.centerx - 10, brick.centery)
effects.append({
"rect": pygame.Rect(brick.x, brick.y, brick.width, brick.height),
"timer": 10
})
brick_sound.play()
bricks.remove(brick)
score += 10
break
for item in items[:]:
item.y += item_speed
if item.colliderect(paddle_rect):
paddle_rect.width += 30
item_sound.play()
items.remove(item)
elif item.top > SCREEN_HEIGHT:
items.remove(item)
for effect in effects[:]:
effect["timer"] -= 1
if effect["timer"] <= 0:
effects.remove(effect)
if ball_rect.top > SCREEN_HEIGHT and ball_active:
lives -= 1
ball_active = False
if lives <= 0:
running = False
else:
paddle_rect.width = paddle_width
paddle_rect.x = (SCREEN_WIDTH - paddle_width) // 2
create_bricks()
items.clear()
effects.clear()
screen.fill(BLACK)
screen.blit(font.render(f"Score: {score}", True, WHITE), (10, 10))
screen.blit(font.render(f"Lives: {lives}", True, WHITE), (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)
for item in items:
pygame.draw.rect(screen, GREEN, item)
for effect in effects:
pygame.draw.rect(screen, EFFECT_COLOR, effect["rect"])
pygame.display.flip()
pygame.quit()
sys.exit()
728x90
'⚙️ Python > 🎮 Pygame 실전' 카테고리의 다른 글
| [Pygame] 🧱 벽돌 깨기 게임 만들기 15강 | 배경음악 추가 (0) | 2026.02.27 |
|---|---|
| [Pygame] 🧱 벽돌 깨기 게임 만들기 14강 | 재시작 기능 추가 (0) | 2026.02.26 |
| [Pygame] 🧱 벽돌 깨기 게임 만들기 12강 | 타이틀 화면 추가 (0) | 2026.02.25 |
| [Pygame] 🧱 벽돌 깨기 게임 만들기 11강 | 이펙트 & 사운드 추가 (0) | 2026.02.25 |
| [Pygame] 🧱 벽돌 깨기 게임 만들기 10강 | 아이템 추가 (0) | 2026.02.24 |