본문 바로가기

programming/pygame

[pygame] 파이썬으로 게임 만들기 - 벽돌깨기

[pygame] 파이썬으로 게임 만들기 - 벽돌깨기

 

안녕하세요. 심심한 코딩쟁이입니다.

 

오늘은 pygame을 활용해 벽돌깨기 게임을 만들어보려고합니다.

 

고전게임 중 하나인 벽돌게임의 룰은 다들 아실테니 바로 만나보시죠.

 

pygame-logo
파이게임


벽돌깨기 전체 코드

 

코드에 주석으로 설명을 달아두었습니다.

 

주석을 보면서 코드를 천천히 이해해 봅시다.

 

import pygame
from random import randrange as rnd

# 게임 창 크기 설정
WIDTH, HEIGHT = 1200, 800
# 게임 속도 설정
fps = 60

# 막대기 설정
bar_w = 330
bar_h = 35
bar_speed = 15
bar = pygame.Rect(WIDTH // 2 - bar_w // 2, HEIGHT - bar_h - 10, bar_w, bar_h)

# 공 설정
ball_radius = 20
ball_speed = 6
ball_rect = int(ball_radius * 2 ** 0.5)
ball = pygame.Rect(rnd(ball_rect, WIDTH - ball_rect), HEIGHT // 2, ball_rect, ball_rect)

# 공의 이동 방향 (dx 1 오른쪽 -1 왼쪽) (dy 1 아래 -1 위)
dx, dy = 1, -1

# 벽돌 설정
block_list = [pygame.Rect(10 + 120 * i, 10 + 70 * j, 100, 50) for i in range(10) for j in range(4)]
color_list = [(rnd(30, 256), rnd(30, 256), rnd(30, 256))for i in range(10) for j in range(4)]

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

# 배경 이미지
background_img = pygame.image.load("background.png")

# 벽돌 또는 막대와 충돌할 때 공의 이동방향 변화를 알아내는 함수
def detect_collision(dx, dy, ball, rect):
    if dx > 0: # 오른쪽으로 움직이면서 충돌
        delta_x = ball.right - rect.left
    else: # 왼쪽으로 움직이면서 충돌
        delta_x = rect.right - ball.left
    
    if dy > 0: # 아래로 움직이면서 충돌
        delta_y = ball.bottom - rect.top
    else: # 위로 움직이면서 충돌
        delta_y = rect.bottom - ball.top
        
    if abs(delta_x - delta_y) < 10: # 모서리에 충돌한 경우
        dx, dy = -dx, -dy # 좌우 상하 이동 방향 전환
    elif delta_x > delta_y: # 위 아래 면과 충돌한 경우
        dy = -dy # 상하 이동 방향 전환
    elif delta_y > delta_x: # 좌 우 면과 충돌한 경우
        dx = -dx # 좌우 이동 방향 전환
    return dx, dy

while True: # 게임 루프
    for event in pygame.event.get():
        if event.type == pygame.QUIT: # 닫기 버튼 (X)를 누르면 게임 종료
            exit() 
    screen.blit(background_img, (0, 0)) # 크기를 설정해둔 화면에 배경 이미지를 심어줌
    
    # 벽돌 그리기
    [pygame.draw.rect(screen, color_list[color], block) for color, block in enumerate(block_list)]
    # 막대 그리기
    pygame.draw.rect(screen, pygame.Color('gray'), bar)
    # 공 그리기
    pygame.draw.circle(screen, pygame.Color('purple'), ball.center, ball_radius)
    
    # 공의 위치 변화
    ball.x += ball_speed * dx
    ball.y += ball_speed * dy
    
    # 공이 좌우 벽 충돌
    if ball.centerx < ball_radius or ball.centerx > WIDTH - ball_radius:
        dx = -dx
    
    # 공이 위쪽 벽 충돌
    if ball.centery < ball_radius:
        dy = -dy
    
    # 공이 막대와 충돌
    if ball.colliderect(bar) and dy > 0:
        dx, dy = detect_collision(dx, dy, ball, bar) # 공의 이동 방향 결정
    
    # 충돌한 벽돌 처리
    hit_index = ball.collidelist(block_list)
    if hit_index != -1:
        hit_rect = block_list.pop(hit_index)
        hit_color = color_list.pop(hit_index)
        dx, dy = detect_collision(dx, dy, ball, hit_rect) # 공의 이동 방향 결정
        # 충돌 시 특수 효과
        hit_rect.inflate_ip(ball.width * 3, ball.height * 3)
        pygame.draw.rect(screen, hit_color, hit_rect)
        fps += 2
    
    # 게임 결과 출력
    if ball.bottom > HEIGHT:
        print("GAME OVER!!")
        exit()
    elif not len(block_list):
        print("WIN!!")
        exit()
        
    # 막대 조작
    key = pygame.key.get_pressed()
    if key[pygame.K_LEFT] and bar.left > 0:
        bar.left -= bar_speed
    if key[pygame.K_RIGHT] and bar.right < WIDTH:
        bar.right += bar_speed
    
    # 화면 업데이트
    pygame.display.flip()
    clock.tick(fps)

실행 화면

 

게임을 실행한 모습입니다.

 

game-screen
게임 실행 화면


게임 방법

 

공이 아래로 떨어지지 않게 막대를 움직이십시오.

 

막대로 공을 튕겨서 벽돌을 모두 깨면 승리입니다.

 

좌우 방향키를 눌러 막대를 조종할 수 있습니다.

 


배경 이미지

 

배경으로 사용한 이미지의 크기는 1200x800 px 입니다.

 

background-img
배경 이미지


여기까지 파이썬으로 게임 만들기 벽돌깨기 편이었습니다.

 

코드에 궁금하신부분이 있으시면 댓글로 남겨주세요. 성심성의껏 답변드리겠습니다.

 

다음에도 재미있는 게임을 구현해서 포스팅하도록 하겠습니다.

 

감사합니다.

반응형