Search

PyGame으로 스베랑카 게임 만들기 (1)

생성일
2025/09/26 06:02
태그
초코쌤
파이썬
파이게임
게임개발
안녕하세요? 초코쌤입니다.
작년(2024년) 11월호에 잠깐 PyGame으로 공룡게임 만들기에 대해서 소개해드렸는데요~
PyGame으로 게임 만들기 시리즈를 이어 가보려고 합니다 ㅎㅎ
이번에는 스베랑카(SUBERUNKER)라는 게임을 만들어보려고 하는데요.
흔히, 똥피하기 게임이라고 하면 모두 한 번쯤은 해보셨을 게임입니다 ㅎㅎ
이번호에서 만들 것은 아래와 같습니다
큰 틀 잡기
플레이어를 움직일 수 있게 하기
떨어지는 도형 만들기
부딪히면 게임 종료
PyGame 세팅작업은 24년 11월호를 참고해주세요

큰 틀 잡기

1.
초깃값 세팅
import pygame #Pygame 기능 쓰기 위함 WIDTH, HEIGHT = 400, 600 # 창 크기 WHITE = (255, 255, 255) BLACK = (0,0,0)
Python
복사
먼저 위와 같이 코드를 작성합니다.
먼저, import pygame을 써주시고, 화면을 세로로 긴 형태로 출력하기 위해 400 x 600 정도로 지정합니다.
하얀색 배경을 쓰기 위해 RGB값을 255, 255, 255로 지정합니다.
왜 하얀색이 (255, 255, 255)일까요?
위 숫자는 각각 Red, Green, Blue 색을 의미하고, 각 색의 밝기는 0~255 숫자로 표현합니다. 0은 어두움, 255는 밝음입니다. 흰색은 RGB를 모두 최대로 밝게 했다고 생각하시면 됩니다. 그러면 검은색은 (0, 0, 0)이겠죠?
2.
Game 클래스 설계
Game 클래스란 게임 자체를 관리하는 클래스라고 생각하면 됩니다.
이렇게 클래스를 활용하여 Game 클래스 하나만으로도 게임의 흐름(입력 → 갱신 → 그리기)을 한눈에 볼 수 있게 하겠습니다.
import pygame #Pygame 기능 쓰기 위함 import sys #sys.exit()를 사용하기 위함 WIDTH, HEIGHT = 400, 600 # 창 크기 FPS = 60 # 초당 60프레임 WHITE = (255, 255, 255) BLACK = (0,0,0) class Game: def __init__(self): pygame.init() # Pygame 초기화 #위에서 설정한 변수로 게임 스크린 크기 설정 self.screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 창 제목 설정 pygame.display.set_caption("Suberunker Game") # FPS를 제어해주는 '시계' 생성 self.clock = pygame.time.Clock() #run이라는 함수를 계속 돌릴지 여부 self.running = True def run(self): while self.running: # running이 True인 동안 계속 반복 self.clock.tick(FPS) # 프레임 속도 제어 for e in pygame.event.get(): # 마우스/키보드 등 이벤트를 꺼낸다. if e.type == pygame.QUIT: # 꺼낸 이벤트가 종료라면 running을 self.running = False # false로 만들어서 게임 종료. self.screen.fill(WHITE) # 배경을 하얀색으로 칠하고 pygame.display.flip() # 화면 업데이트 pygame.quit() #Pygame 닫기 sys.exit() #파이썬 프로그램 완전 종료 game = Game() game.run()
Python
복사
위와 같이 코드를 작성하면 아래와 같은 하얀색 실행 화면을 확인할 수 있습니다.
FPS란 Frame Per Second로 ‘초당 프레임이 몇이냐?’ 를 의미합니다. 60fps는 초당 60장의 그림을 빠르게 넘겨 보여준다고 생각하면 됩니다. 마치 플립 북 애니메이션이라고 생각하시면 이해가 빠르실 겁니다.
import sys를 한 이유는 IDLE에서 개발하고 있기 때문인데, 파이썬 프로그램을 완전히 종료(sys.exit())하기 위함입니다. visual studio code 등의 환경에서는 신경 안 써도 됩니다.

플레이어를 움직일 수 있게 하기

1.
플레이어 클래스 설계하기
플레이어가 필요한 것을 먼저 생각해 보겠습니다.
먼저 플레이어는 사각형으로 그릴 것이고, 색깔과 속도라는 특성을 주겠습니다.
import pygame #Pygame 기능 쓰기 위함 import sys #sys.exit()를 사용하기 위함 WIDTH, HEIGHT = 400, 600 # 창 크기 FPS = 60 # 초당 60프레임 WHITE = (255, 255, 255) BLACK = (0,0,0) class Player: def __init__(self, x, y, w=40, h=40, speed=5, color=BLACK): self.rect = pygame.Rect(x, y, w, h) # 위치/크기 self.speed = speed # 한 프레임당 이동 픽셀 self.color = color
Python
복사
이번엔 키가 눌렸을 때 움직일 수 있게 하고, 그리는 함수를 추가하겠습니다.
import pygame #Pygame 기능 쓰기 위함 import sys #sys.exit()를 사용하기 위함 WIDTH, HEIGHT = 400, 600 # 창 크기 FPS = 60 # 초당 60프레임 WHITE = (255, 255, 255) BLACK = (0,0,0) class Player: def __init__(self, x, y, w, h, speed, color): self.rect = pygame.Rect(x, y, w, h) # 위치/크기 self.speed = speed # 한 프레임당 이동 픽셀 self.color = color def handle_input(self): # 현재 눌려 있는 키 상태를 한 번에 가져옵니다. keys = pygame.key.get_pressed() # ← 방향키가 눌렸으면 x값을 감소시켜서 위치를 왼쪽으로 이동 if keys[pygame.K_LEFT]: self.rect.x -= self.speed # → 방향키가 눌렸으면 x값을 증가시켜서 위치를 오른쪽으로 이동 if keys[pygame.K_RIGHT]: self.rect.x += self.speed def draw(self, screen): # 플레이어(검정 사각형) 그리기 pygame.draw.rect(screen, self.color, self.rect)
Python
복사
PyGame에서는 좌표계를 위 그림과 같이 쓰기 때문에 왼쪽으로 이동하려면 빼고 오른쪽으로 이동하려면 더해야 하는 것입니다.
위와 코드를 작성했다면 Game 클래스에 아래와 같이 추가해 봅시다.
class Game: def __init__(self): pygame.init() # Pygame 초기화 #위에서 설정한 변수로 게임 스크린 크기 설정 self.screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 창 제목 설정 pygame.display.set_caption("Suberunker Game") # FPS를 제어해주는 '시계' 생성 self.clock = pygame.time.Clock() #run이라는 함수를 계속 돌릴지 여부 self.running = True # 플레이어 화면 아래 중앙 배치 px = WIDTH//2 - 20; py = HEIGHT - 60 self.player = Player(px, py, 40, 40, 5, BLACK) def run(self): while self.running: # running이 True인 동안 계속 반복 self.clock.tick(FPS) # 프레임 속도 제어 for e in pygame.event.get(): # 마우스/키보드 등 이벤트를 꺼낸다. if e.type == pygame.QUIT: # 꺼낸 이벤트가 종료라면 running을 self.running = False # false로 만들어서 게임 종료. self.player.handle_input() # 입력처리 self.screen.fill(WHITE) # 배경을 하얀색으로 칠하고 self.player.draw(self.screen) # 플레이어 그리기 pygame.display.flip() # 화면 업데이트 pygame.quit() #Pygame 닫기 sys.exit() #파이썬 프로그램 완전 종료
Python
복사
⇒ 그럼 이렇게 플레이어가 나오고 좌우로 움직여집니다 ㅎㅎ
여기서 speed 값을 바꾸면 누를 때마다 이동 감도가 확 달라지는 것을 느낄 수 있을 겁니다.

떨어지는 도형 만들기

갈색을 추가하고, 떨어질 도형의 크기를 지정하겠습니다.
import pygame #Pygame 기능 쓰기 위함 import sys #sys.exit()를 사용하기 위함 WIDTH, HEIGHT = 400, 600 # 창 크기 FPS = 60 # 초당 60프레임 WHITE = (255, 255, 255) BLACK = (0,0,0) BROWN = (150, 75, 0) OBJECT_SIZE = 30
Python
복사
FallObject 클래스를 Player 클래스 아래에다가 붙여봅시다.
class FallObject: def __init__(self): x = random.randint(0, WIDTH - OBJECT_SIZE ) y = -OBJECT_SIZE # 화면 위(밖)에서 시작 self.rect = pygame.Rect(x, y, OBJECT_SIZE , OBJECT_SIZE ) self.speed = 5 # 낙하 속도 def update(self): self.rect.y += self.speed def draw(self, screen): cx, cy = self.rect.center r = OBJECT_SIZE // 2 pygame.draw.circle(screen, BROWN, (cx, cy), r)
Python
복사
Game 클래스 Player 생성 아래에다가 리스트와 스폰 타이머를 추가하겠습니다.
class Game: def __init__(self): pygame.init() # Pygame 초기화 #위에서 설정한 변수로 게임 스크린 크기 설정 self.screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 창 제목 설정 pygame.display.set_caption("Suberunker Game") # FPS를 제어해주는 '시계' 생성 self.clock = pygame.time.Clock() #run이라는 함수를 계속 돌릴지 여부 self.running = True # 플레이어 화면 아래 중앙 배치 px = WIDTH//2 - 20; py = HEIGHT - 60 self.player = Player(px, py, 40, 40, 5, BLACK) # 떨어지는 오브젝트 리스트 self.objects = [] # 일정 주기로 자동 생성되는 이벤트 self.SPAWN = pygame.USEREVENT + 1 pygame.time.set_timer(self.SPAWN, 600)
Python
복사
아래와 같이 spawn_object, update_objects, draw_objects 메서드를 만들겠습니다.
class Game: def __init__(self): # Game 객체가 만들어질 때 한 번 실행 pygame.init() # 1) Pygame 내부 모듈 초기화 self.screen = pygame.display.set_mode( # 2) 게임 창(스크린) 만들기 (WIDTH, HEIGHT) ) pygame.display.set_caption("Suberunker Game")# 3) 창 제목(캡션) 지정 self.clock = pygame.time.Clock() # 4) FPS를 제어해주는 '시계' 생성 self.running = True # 5) 메인 루프를 돌릴지 여부(True면 계속) # 플레이어 화면 아래 중앙 배치 px = WIDTH//2 - 20; py = HEIGHT - 60 self.player = Player(px, py, 40, 40, 5, BLACK) # 떨어지는 오브젝트 리스트 self.objects = [] # 일정 주기로 자동 생성되는 이벤트 self.SPAWN = pygame.USEREVENT + 1 pygame.time.set_timer(self.SPAWN, 600) def spawn_object(self): self.objects.append(FallObject()) def update_objects(self): for p in self.objects[:]: p.update() def draw_objects(self): for p in self.objects: p.draw(self.screen)
Python
복사
Game클래스의 run메서드를 아래와 같이 추가합니다. 갱신되어야 하는 시점에 플레이어 입력과 같이 오브젝트도 떨어뜨릴 수 있게 하겠습니다.
def run(self): while self.running: # running이 True인 동안 계속 반복 self.clock.tick(FPS) # 프레임 속도 제어 for e in pygame.event.get(): # 마우스/키보드 등 이벤트를 꺼낸다. if e.type == pygame.QUIT: # 꺼낸 이벤트가 종료라면 running을 self.running = False # false로 만들어서 게임 종료. self.player.handle_input() # 입력처리 self.update_objects() self.screen.fill(WHITE) # 배경을 하얀색으로 칠하고 self.player.draw(self.screen) # 플레이어 그리기 self.draw_objects() pygame.display.flip() # 화면 업데이트 pygame.quit() #Pygame 닫기 sys.exit() #파이썬 프로그램 완전 종료
Python
복사
여기까지 잘 따라오셨으면 아래와 같이 동그라미 오브젝트가 떨어지는 것을 확인할 수 있습니다.

부딪히면 게임 종료

이제 충돌 처리를 해보겠습니다.
지난 공룡 게임에서 활용했던 colliderect를 활용해 보겠습니다.
아래와 같이 Game 클래스에 check_collision 메서드를 추가해 주세요.
def check_collision(self): for p in self.objects: if self.player.rect.colliderect(p.rect): self.running = False # ← '맞으면 끝' break
Python
복사
그리고 우리의 게임이 돌아가고 있는 run으로 와서 이제 저 메서드를 호출해야 합니다. 어디서 호출하는 게 좋을까요?
바로, 장애물이 움직이고 난 뒤인 update_objects() 직후입니다.
def run(self): while self.running: # running이 True인 동안 계속 반복 self.clock.tick(FPS) # 프레임 속도 제어 for e in pygame.event.get(): # 마우스/키보드 등 이벤트를 꺼낸다. if e.type == pygame.QUIT: # 꺼낸 이벤트가 종료라면 running을 self.running = False # false로 만들어서 게임 종료. self.player.handle_input() # 입력처리 self.update_objects() self.check_collision() # 충돌감지 self.screen.fill(WHITE) # 배경을 하얀색으로 칠하고 self.player.draw(self.screen) # 플레이어 그리기 self.draw_objects() pygame.display.flip() # 화면 업데이트 pygame.quit() #Pygame 닫기 sys.exit() #파이썬 프로그램 완전 종료
Python
복사
여기까지 잘 따라오셨다면, 실행하고 나서 떨어지는 오브젝트와 충돌나면 게임이 종료될 것입니다.
게임이 갑자기 툭 꺼져도 정상이니 걱정하지 않으셔도 됩니다
이렇게 한 줄 한 줄 쌓다 보니 벌써 게임이 완성됐습니다.
“게임은 즐기는 것”이기도 하지만, “직접 만드는 것”은 더 큰 즐거움이라는 것을 학생들에게 알려주는 것은 어떨까요?
다음 호에서는 점수와 다양한 요소를 더해, 이 게임을 더 발전된 글로 찾아뵙겠습니다