본문 바로가기
컬러풀한 창작물

"파이썬과 Pygame으로 만든 공 터트리기 게임: 개발 과정 및 코드 설명"

by 컬러풀한 창작물 2024. 7. 14.

파이썬과 Pygame을 사용하여 재미있는 공 터트리기 게임을 만드는 방법을 알아보세요. 단계별 코드 설명과 함께 게임 개발의 기본 개념을 익히고, 나만의 게임을 만들어보세요.

파이썬과 Pygame으로 만든 공 터트리기 게임: 개발 과정 및 코드 설명

"파이썬과 Pygame으로 만든 공 터트리기 게임: 개발 과정 및 코드 설명"

 

파이썬으로 만든 공 터트리기 게임 소개

 

안녕하세요, 게임 개발에 관심이 있으신 여러분! 오늘은 파이썬(Python)과 파이게임(Pygame) 라이브러리를 사용하여 만든 재미있는 공 터트리기 게임을 소개해드리겠습니다. 이 게임은 간단한 조작과 흥미진진한 플레이로 시간 가는 줄 모르게 할 것입니다.

파이썬과 Pygame으로 만든 공 터트리기 게임

 

게임의 주요 목표

 

1) 모든 공을 없애면 게임 종료 (성공)

2) 캐릭터가 공에 닿으면 게임 종료 (실패)

3) 시간 제한 99초 초과 시 게임 종료 (실패)

 

 

게임의 기본 구조

 

1. 초기 설정

게임이 시작되면 화면 크기, 타이틀, FPS 등을 설정합니다. 이는 파이게임에서 기본적으로 필요한 초기화 작업입니다.

pygame.init()
screen_width = 640
screen_height = 480
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("공 터트리기 게임")
clock = pygame.time.Clock()

 

2. 게임에 필요한 리소스 로드

게임에서 사용할 배경, 스테이지, 캐릭터, 무기, 공 이미지들을 불러옵니다.

current_path = os.path.dirname(__file__)
image_path = os.path.join(current_path, "images")

background = pygame.image.load(os.path.join(image_path, "background.png"))
stage = pygame.image.load(os.path.join(image_path, "stage.png"))
character = pygame.image.load(os.path.join(image_path, "character.png"))
weapon = pygame.image.load(os.path.join(image_path, "weapon.png"))

ball_images = [
    pygame.image.load(os.path.join(image_path, "ball1.png")),
    pygame.image.load(os.path.join(image_path, "ball2.png")),
    pygame.image.load(os.path.join(image_path, "ball3.png")),
    pygame.image.load(os.path.join(image_path, "ball4.png"))
]

 

파이썬과 Pygame으로 만든 공 터트리기 게임: 배경 이미지 파이썬과 Pygame으로 만든 공 터트리기 게임: 캐릭터 이미지
게임에서 사용된 배경, 캐릭터

 

파이썬과 Pygame으로 만든 공 터트리기 게임: 공 이미지
게임에서 사용된 공
파이썬과 Pygame으로 만든 공 터트리기 게임: 무기

 

3. 게임 루프

게임이 실행되는 동안에는 여러 가지 이벤트 처리가 이루어집니다. 키보드 입력을 받아 캐릭터를 이동시키고, 스페이스바를 누르면 무기를 발사합니다.

running = True
while running:
    dt = clock.tick(30)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                character_to_x -= character_speed
            elif event.key == pygame.K_RIGHT:
                character_to_x += character_speed
            elif event.key == pygame.K_SPACE:
                weapon_x_pos = character_x_pos + (character_width / 2) - (weapon_width / 2)
                weapon_y_pos = character_y_pos
                weapons.append([weapon_x_pos, weapon_y_pos])
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                character_to_x = 0

 

4. 게임 캐릭터 및 무기 이동

캐릭터와 무기의 위치를 업데이트하고, 무기가 천장에 닿으면 제거합니다.

character_x_pos += character_to_x
if character_x_pos < 0:
    character_x_pos = 0
elif character_x_pos > screen_width - character_width:
    character_x_pos = screen_width - character_width

weapons = [ [w[0], w[1] - weapon_speed] for w in weapons]
weapons = [[w[0], w[1]] for w in weapons if w[1] > 0]

 

5. 공 위치 정의 및 충돌 처리

공이 화면의 벽에 닿으면 튕겨 나오는 효과를 주고, 공과 캐릭터, 공과 무기가 충돌하는지를 검사합니다. 충돌 시에는 공을 나눠서 작은 공을 생성하거나 게임을 종료합니다.

for ball_idx, ball_val in enumerate(balls):
    ball_pos_x = ball_val["pos_x"]
    ball_pos_y = ball_val["pos_y"]
    ball_img_idx = ball_val["img_idx"]
    
    ball_size = ball_images[ball_img_idx].get_rect().size
    ball_width = ball_size[0]
    ball_height = ball_size[1]
    
    if ball_pos_x < 0 or ball_pos_x > screen_width - ball_width:
        ball_val["to_x"] *= -1
        
    if ball_pos_y >= screen_height - stage_height - ball_height:
        ball_val["to_y"] = ball_val["init_spd_y"]
    else:
        ball_val["to_y"] += 0.5
    
    ball_val["pos_x"] += ball_val["to_x"]
    ball_val["pos_y"] += ball_val["to_y"]

    if character_rect.colliderect(ball_rect):
        running = False
        break
    
    for weapon_idx, weapon_val in enumerate(weapons):
        weapon_pos_x = weapon_val[0]
        weapon_pos_y = weapon_val[1]
        
        weapon_rect = weapon.get_rect()
        weapon_rect.left = weapon_pos_x
        weapon_rect.top = weapon_pos_y
        
        if weapon_rect.colliderect(ball_rect):
            weapon_to_remove = weapon_idx
            ball_to_remove = ball_idx
            
            if ball_img_idx < 3:
                ball_width = ball_rect.size[0]
                ball_height = ball_rect.size[1]
                
                small_ball_rect = ball_images[ball_img_idx + 1].get_rect()
                small_ball_width = small_ball_rect.size[0]
                small_ball_height = small_ball_rect.size[1]
                
                balls.append({
                    "pos_x": ball_pos_x + (ball_width / 2) - (small_ball_width / 2),
                    "pos_y": ball_pos_y + (ball_height / 2) - (small_ball_height / 2),
                    "img_idx": ball_img_idx + 1,
                    "to_x": -3,
                    "to_y": -6,
                    "init_spd_y": ball_speed_y[ball_img_idx + 1]
                })
                balls.append({
                    "pos_x": ball_pos_x + (ball_width / 2) - (small_ball_width / 2),
                    "pos_y": ball_pos_y + (ball_height / 2) - (small_ball_height / 2),
                    "img_idx": ball_img_idx + 1,
                    "to_x": 3,
                    "to_y": -6,
                    "init_spd_y": ball_speed_y[ball_img_idx + 1]
                })
            break
    else:
        continue
    break

if ball_to_remove > -1:
    del balls[ball_to_remove]
    ball_to_remove = -1

if weapon_to_remove > -1:
    del weapons[weapon_to_remove]
    weapon_to_remove = -1

if len(balls) == 0:
    game_result = "Mission Complete"
    running = False

 

6. 화면 그리기

각 프레임마다 배경, 무기, 공, 캐릭터, 스테이지를 화면에 그려줍니다. 또한, 남은 시간을 계산하여 표시합니다.

screen.blit(background, (0, 0))
for weapon_x_pos, weapon_y_pos in weapons:
    screen.blit(weapon, (weapon_x_pos, weapon_y_pos))
for idx, val in enumerate(balls):
    ball_pos_x = val["pos_x"]
    ball_pos_y = val["pos_y"]
    ball_img_idx = val["img_idx"]
    screen.blit(ball_images[ball_img_idx], (ball_pos_x, ball_pos_y))
screen.blit(stage, (0, screen_height - stage_height))
screen.blit(character, (character_x_pos, character_y_pos))

elapsed_time = (pygame.time.get_ticks() - start_ticks) / 1000
timer = game_font.render("Time : {}".format(int(total_time - elapsed_time)), True, (255, 255, 255))
screen.blit(timer, (10, 10))

if total_time - elapsed_time <= 0:
    game_result = "Time Over"
    running = False

pygame.display.update()

 

7. 게임 종료 처리

게임이 종료되면 결과 메시지를 표시하고 2초 대기한 후 게임을 종료합니다.

msg = game_font.render(game_result, True, (255, 255, 0))
msg_rect = msg.get_rect(center=(int(screen_width / 2), int(screen_height / 2)))
screen.blit(msg, msg_rect)
pygame.display.update()
pygame.time.delay(2000)
pygame.quit()
파이썬과 Pygame으로 만든 공 터트리기 게임

 

마무리

 

이 게임은 파이썬과 파이게임을 사용하여 손쉽게 구현할 수 있으며, 게임 개발의 기본적인 흐름을 익히기에 좋은 예제입니다. 여러분도 한번 도전해보세요! 더 흥미로운 기능들을 추가하여 나만의 멋진 게임을 만들어보세요!

 

 

"파이썬으로 간단한 똥 피하기 게임 만들기: 초보자를 위한 Pygame 튜토리얼"

 

"파이썬으로 간단한 똥 피하기 게임 만들기: 초보자를 위한 Pygame 튜토리얼"

이 튜토리얼에서는 Python과 Pygame을 이용해 간단한 똥 피하기 게임을 만드는 방법을 소개합니다. 초보자도 쉽게 따라 할 수 있는 코드와 설명을 제공합니다."파이썬으로 간단한 똥

colorful-creations.tistory.com

 

"스테이블 디퓨전과 AnimateDiff로 만든 무서운 이야기 AI 애니메이션 작품"

 

"스테이블 디퓨전과 AnimateDiff로 만든 무서운 이야기 AI 애니메이션 작품"

스테이블 디퓨전과 AnimateDiff 기술을 활용해 변화하는 무서운 소녀 캐릭터를 생동감 있게 표현한 고퀄리티 AI 애니메이션 작품을 소개합니다. 디지털 아트의 새로운 가능성을 확

colorful-creations.tistory.com