본문 바로가기

[Pygame] 🧱 벽돌 깨기 게임 만들기 5강 | 패들과 공 충돌 처리

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


패들과 공 충돌 처리

이번 강의에서는 공이 패들과 충돌했을 때 튕기도록 처리합니다.
이 과정을 통해 벽돌깨기 게임의 핵심 재미 요소인
플레이어 조작에 따른 공의 반응을 구현합니다.

이 강의가 끝나면
공은 패들에 맞고 다시 위로 튕기게 됩니다.


패들 충돌의 특징

벽 충돌과 패들 충돌은 중요한 차이가 있습니다.

  • 벽은 고정되어 있습니다
  • 패들은 플레이어가 직접 움직입니다

따라서 패들과의 충돌은
단순히 방향만 바꾸는 것이 아니라
게임 플레이에 직접적인 영향을 주는 충돌입니다.

이번 강의에서는 먼저
가장 기본적인 형태의 패들 충돌을 구현합니다.


Rect를 이용한 충돌 판정

파이게임에서는 Rect 객체끼리의 충돌을
아주 간단하게 확인할 수 있습니다.

if ball_rect.colliderect(paddle_rect):
    ball_speed_y *= -1

colliderect() 함수는
두 사각형이 겹치는 순간 True를 반환합니다.

이 코드로
공이 패들에 닿았는지를 확인할 수 있습니다.


공이 패들에 닿았을 때 발생하는 문제

위 코드만 사용하면
공이 패들 안에 계속 겹쳐 있으면서
속도가 여러 번 반전되는 문제가 발생할 수 있습니다.

이를 방지하기 위해
충돌 직후 공의 위치를 조정해야 합니다.


충돌 후 공 위치 보정

공이 패들 위쪽에 정확히 위치하도록
공의 y좌표를 보정합니다.

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

이 처리를 통해
공이 패들 내부에 머무르지 않고
자연스럽게 튕기게 됩니다.


패들 충돌 처리의 순서

패들과의 충돌 처리는
반드시 다음 순서로 진행해야 합니다.

  • 공 이동
  • Rect 위치 갱신
  • 패들과의 충돌 확인
  • 속도 반전
  • 위치 보정

이 순서를 지키지 않으면
충돌이 불안정하게 동작할 수 있습니다.


현재 단계의 결과

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

  • 공이 벽에 부딪히면 튕깁니다
  • 공이 패들에 닿으면 위로 튕깁니다
  • 패들을 움직이며 공의 낙하를 막을 수 있습니다

이제 벽돌깨기 게임의 기본 조작이
실제로 게임처럼 동작하기 시작합니다.

다음 강의에서는
화면 상단에 벽돌을 생성하는 구조를 구현합니다.



전체 코드

더보기
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)

# FPS 설정
clock = pygame.time.Clock()
FPS = 60

# 패들 설정
paddle_width = 100
paddle_height = 15
paddle_speed = 7

paddle_x = (SCREEN_WIDTH - paddle_width) // 2
paddle_y = SCREEN_HEIGHT - 40

paddle_rect = pygame.Rect(
    paddle_x,
    paddle_y,
    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
)

# 게임 루프
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

    if paddle_rect.left < 0:
        paddle_rect.left = 0
    if paddle_rect.right > SCREEN_WIDTH:
        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

    # 화면 그리기
    screen.fill(BLACK)
    pygame.draw.rect(screen, WHITE, paddle_rect)
    pygame.draw.circle(screen, WHITE, (ball_x, ball_y), ball_radius)
    pygame.display.flip()

pygame.quit()
sys.exit()

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

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

목차