Python/pygame

파이썬으로 게임 만들기(Pygame) - 5. 애니메이션과 프레임

wtc 2024. 6. 15. 14:06

 

강의를 보기 전 이전 강의인 파이썬으로 게임 만들기(Pygame) - 4. 이미지 로딩과 표시하기를 꼭 읽기를 추천한다.

 

Spritesheet를 이용해 애니메이션 만들기


Spritesheet를 이용해 animation을 만들기 위한 함수와 메서드들

pygame.image.load('이미지 경로')

- 이미지를 불러오는 메서드

pygmae.image.load('이미지 경로').subsurface(x축, y축, width,height)

- 불러온 이미지를 새로 잘라내는 메서드

pygame.time.Clock()

- Frame rate를 관리할 수 있는 객체

pygame.time.Clock.tick()

- 프레임 속도조를 조절하는 메서드, 프로그램이 일정한 속도로 실행되게 함

 

pygame.time.get_ticks()

- 현재 시간을 밀리초 단위로 반환하는 메서드

 


완성본 코드

import pygame, sys

pygame.init() # pygame 초기화

pd = pygame.display
size = (800,600) # 화면 사이즈
screen = pd.set_mode(size) # 화면 사이즈 설정

pd.set_caption('animation test') # 게임 타이틀

white = (255, 255, 255) # rgb (흰색)

ss = pygame.image.load('img\spritesheet.jpg') # spritesheet 로드

screen.fill(white) # 게임 배경을 흰색으로 설정
pd.flip() # 화면 업데이트

# 프레임 정보, 현재 spritesheet는 32x32의 프레임이 9개가 3x3 모양으로 있다.
frame_width = 32
frame_height = 32
total_frames = 9
current_frame = 0

#시간을 관리해줄 객체 생성
time = pygame.time.Clock()
last_update_time = pygame.time.get_ticks()

# 1초에 frame을 10번 반복하게 됨
frame_rate = 10
frame_duration = 1000 // frame_rate 

running = True # 게임 루프를 위한 변수

while running: # 게임 루프(실행 중)
    current_time = pygame.time.get_ticks() #현재시간 저장
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False # x(화면 닫기 버튼)을 눌렀을 때 프로그램 종료
        
    if current_time - last_update_time > frame_duration:
        current_frame = (current_frame + 1) % total_frames
        last_update_time = current_time

    x = (current_frame % 3) * frame_width
    y = (current_frame // 3) * frame_height
    sprite = ss.subsurface(x, y, frame_width, frame_height)

    screen.fill(white)
    screen.blit(sprite, (300,200))
    pd.flip()
                    
    time.tick(60)

pygame.quit()
sys.exit()

식 설명과 과정

1. Spritesheet를 불러오기

ss = pygame.image.loud('Spritesheet경로') # Spritesheet 로드

 

2. 프레임의 크기와 총 프레임 수 변수 선언

frame_width =32 # frame의 가로 크기
frame_height = 32 # frame의 세로 크기
total_frames = 9 # Spritesheet 안의 frame 갯수

 

3. 애니메이션 설정을 위한 변수 선언

current_frame = 0 # 제일 먼저 보여질 프레임의 인덱스를 0으로 초기화

clock = pygame.time.Clock() # 시간을 관리하게 해주는 기능의 객채
# .tick(틱 설정)이나 .get_time(tick이 마지막으로 호출된 이후 시간) 등 시간을 관리하는 기능을 사용

frame_rate = 10 # 1초마다 반복 될 frame 수

frame_duration = 1000 // frame_rate 
# 여기서 1000은 1초(1000ms)로 frame_rate 변수로 나눠 1초마다 10번 반복을 뜻

last_update_time = pygame.time.get_ticks()
# 프로그램이 시작된 이후 경과된 시간을 저장

 

4. 게임 실행 이후 (while문 내부)

current_time = pygame.time.get_ticks()
# 현재 시간을 저장

 

if current_time - last_update_time > frame_duration:
# 현재시간 - 마지막 프레임 변경시간이 frame_duration(프레임 변경시간)보다 크면 if문 실행

	current_frame = (current_frame + 1) % total_frames
    # 다음 프레임으로 넘어가기 위한 식, 프레임이 총 9개이니 9번째 프레임이 되면 9 % 9 식으로 다시 0 이 됨
    last_update_time = current_time
    # 마지막 프레임 변경시간을 현재시간으로 저장

 

5. Spritesheet, subsurface를 이용해 프레임 나누기

# 3x3 spritesheet 일 때의 기준
x = (current_frame % 3) * frame_width
# 현재 프레임의 인덱스에 3을 나눈 후 나머지를 width에 곱하면서 spritesheet x좌표 설정
y = (current_frame // 3) * frame_height
# 현재 프레임의 인덱스에 3을 나눈 후 몫을 height에 곱하면서 spritesheet y좌표 설정\

coordinate = (x, y, frame_width, frame_height)
# 프레임의 좌표와 크기를 저장

sprite = ss.subsurface(coordinate)
# 잘라낸 프레임을 저장

screen.fill(255,255,255) # 배경을 흰색으로 채움, 생성됐던 프레임을 제거하기 위해
screen.blit(sprite, (100,100)) # 100, 100 좌표에 프레임 생성
pygame.display.flip() #화면 업데이트

 

6. 프레임 설정

clock.tick(60)
# 게임을 60fps로 설정, 1초에 60번 이상 무언가 실행하려하면 실행을 막아준다.