개발/Python

[Python] 파이썬으로 고전 게임 러너게임 만들기 - 다섯번째 게임

일요일좋아하는사람 2025. 4. 22. 19:51
728x90
반응형

고전게임 시리즈

1. 테트리스

https://ilikesunday.tistory.com/31

 

[Python] 파이썬으로 고전 게임 '테트리스' 만들기 – 직접 만들어보며 배운 시행착오의 기록

들어가며예전부터 한 번쯤은 만들어보고 싶었던 게임이 있다면 단연코 테트리스였다. 간단한 구조지만 의외로 중독성이 있고, 적당한 난이도 조절과 함께 구현할 수 있다면 파이썬의 GUI 및 로

ilikesunday.tistory.com

 

 

2. 스네이크게임

https://ilikesunday.tistory.com/32

 

[Python] 파이썬으로 고전 게임 스네이크 게임 만들기 - 삽질의 연속 ㅠㅠ

들어가며처음에는 파이썬으로 테트리스를 먼저 만들었었다. 다른 고전 게임에도 흥미가 생기기도 하고 시리즈별로 만들고 싶어서 스네이크 게임을 만들고자 했지만... 테트리스 때와 달리 이번

ilikesunday.tistory.com

 

3. 벽돌깨기

https://ilikesunday.tistory.com/33

 

[Python] 파이썬으로 고전 게임 벽돌깨기 만들기

고전게임 시리즈1. 테트리스https://ilikesunday.tistory.com/31 [Python] 파이썬으로 고전 게임 '테트리스' 만들기 – 직접 만들어보며 배운 시행착오의 기록들어가며예전부터 한 번쯤은 만들어보고 싶었던

ilikesunday.tistory.com

 

4. 슈팅게임

https://ilikesunday.tistory.com/34

 

[Python] 파이썬으로 고전 게임 슈팅 게임 만들기: 총알, 적, 그리고 리듬감

고전게임 시리즈1. 테트리스https://ilikesunday.tistory.com/31 [Python] 파이썬으로 고전 게임 '테트리스' 만들기 – 직접 만들어보며 배운 시행착오의 기록들어가며예전부터 한 번쯤은 만들어보고 싶었던

ilikesunday.tistory.com

 

끝없이 달리고, 뛰고, 피하라

이전까지 만들었던 게임들에서는 키보드를 눌러야 움직이고, 뭔가를 쏘거나 피해야 했다. 하지만 이번에 만들고자 했던 러너 게임은 조금 다르다. 캐릭터는 자동으로 앞으로 나아가고, 유저는 단지 타이밍에 맞춰 '점프'만 잘 하면 된다. 오직 점프 하나로만 플레이가 이루어지는 게임. 이게 재미있을 수 있을까? 의문은 있었지만, 막상 구현을 시작해보니 이 단순한 메커니즘 속에 은근히 많은 고민과 디테일이 숨어 있었다.

러너 게임은 보통 무한히 이어지는 배경 속에서, 바닥과 장애물이 연속적으로 등장하며 플레이어를 시험한다. 구현적으로는 '중력', '속도 유지', '장애물과 충돌 감지', '점프의 곡선' 등이 주요 요소다. 하지만 그보다 더 중요한 건 점프의 타이밍이 '직관적'이어야 한다는 점이다. 이번 글에서는 러너 게임을 구현하며 어떤 방식으로 캐릭터를 뛰게 만들었는지, 점프 감각을 위해 어떤 테스트를 반복했는지, 충돌 판정과 바닥 처리에서 어떤 실수를 했는지를 모두 기록하고자 한다.

캐릭터와 바닥, 점프 그리고 충돌

러너 게임을 만들기 위해 가장 먼저 생각한 건, 캐릭터가 바닥에 붙어 있고, spacebar를 누르면 위로 튀어오르도록 만드는 것이었다. 아래는 초기 캐릭터 설정 코드이다.

player = pygame.Rect(50, 500, 50, 50)
player_velocity = 0
jumping = False
gravity = 0.5
jump_power = -10

처음엔 jumping 플래그 없이 구현했는데, 이러면 공중에서도 점프가 계속 가능해져서 하늘로 날아가 버리는 일이 생겼다. 그래서 점프는 '바닥에 닿았을 때만' 가능하도록 조건을 걸었다.

if keys[pygame.K_SPACE] and not jumping:
    player_velocity = jump_power
    jumping = True

그리고 매 루프마다 중력을 적용해 플레이어가 아래로 끌려가도록 만들었다.

player_velocity += gravity
player.y += player_velocity

하지만 여기서 중요한 건, 언제 착지했는지 감지하는 것이다. 그냥 if player.y >= ground_y:로만 처리하면 착지 시 y좌표가 부정확하게 튀는 일이 생겼다. 그래서 정확히 바닥에 도달했을 때만 점프를 초기화하도록 조절했다.

if player.y >= 500:
    player.y = 500
    player_velocity = 0
    jumping = False

장애물 구현 – 끊임없이 다가오는 위협

러너 게임에서 장애물은 플레이어를 시험하는 핵심이다. 일정한 간격으로 왼쪽에서 오른쪽으로 다가오는 장애물을 구현했다. 장애물은 리스트에 담고, 계속 이동시킨다.

obstacles = []
obstacle_speed = 5

# 매 루프마다
for obs in obstacles:
    obs.x -= obstacle_speed

일정 간격으로 새로운 장애물을 생성한다.

if len(obstacles) < 5:
    new_obs = pygame.Rect(800, 500, 40, 40)
    obstacles.append(new_obs)

그리고 플레이어와 충돌하면 게임을 종료한다.

for obs in obstacles:
    if player.colliderect(obs):
        game_over = True

전체 코드

import pygame
import random

pygame.init()

WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Runner Game")
clock = pygame.time.Clock()

# 플레이어 설정
player = pygame.Rect(50, 500, 50, 50)
player_velocity = 0
jumping = False
gravity = 0.5
jump_power = -10

# 장애물 설정
obstacles = []
obstacle_speed = 5

# 점수 및 게임 상태
score = 0
font = pygame.font.SysFont(None, 36)
game_over = False
running = True

while running:
    clock.tick(60)
    screen.fill((30, 30, 30))

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

    keys = pygame.key.get_pressed()
    if keys[pygame.K_SPACE] and not jumping:
        player_velocity = jump_power
        jumping = True

    # 중력 적용
    player_velocity += gravity
    player.y += player_velocity

    if player.y >= 500:
        player.y = 500
        player_velocity = 0
        jumping = False

    # 장애물 이동 및 생성
    for obs in obstacles[:]:
        obs.x -= obstacle_speed
        if obs.x < -50:
            obstacles.remove(obs)
            score += 1

    if len(obstacles) < 5:
        if random.randint(0, 60) == 0:
            new_obs = pygame.Rect(800, 500, 40, 40)
            obstacles.append(new_obs)

    # 충돌 감지
    for obs in obstacles:
        if player.colliderect(obs):
            game_over = True

    # 그리기
    pygame.draw.rect(screen, (0, 200, 255), player)
    for obs in obstacles:
        pygame.draw.rect(screen, (255, 100, 100), obs)

    score_text = font.render(f"Score: {score}", True, (255, 255, 255))
    screen.blit(score_text, (10, 10))

    if game_over:
        msg = font.render("Game Over", True, (255, 0, 0))
        screen.blit(msg, (WIDTH // 2 - 80, HEIGHT // 2))
        pygame.display.flip()
        pygame.time.delay(2000)
        running = False

    pygame.display.flip()

pygame.quit()

마무리하며

러너 게임은 생각보다 훨씬 많은 물리 처리가 들어가는 게임이었다. 단순히 점프 하나만 구현하는 줄 알았지만, 점프 타이밍, 중력 계산, 착지 조건, 장애물 생성 타이밍, 게임 오버 시점까지 모든 것이 맞물려야 매끄러운 플레이가 된다. 이번 프로젝트를 통해 '단순한 게임'이 오히려 구현할 땐 더 섬세해야 한다는 걸 배웠다. 하지만 그만큼 완성했을 때의 뿌듯함도 컸다. 이제 여러분도 점프 하나로 시작해보자. 달리기만 해도 충분히 재밌는 게임이 기다리고 있다.


티스토리용 태그

#파이썬 #pygame #러너게임 #게임만들기 #코딩입문 #파이썬게임 #게임프로그래밍 #python #게임개발 #pygame예제

728x90
반응형