모든 프레임 속도에서 부드럽게
Coddy Pygame 여정의 사운드와 게임의 손맛 섹션에 포함된 레슨. 23개 중 19번째.
x += (target_x - x) * 0.1은 프레임마다 이동 거리의 10분의 1만큼 이동합니다. 초당 60프레임이면 초당 60번 이동합니다. 30프레임만 처리할 수 있는 느린 컴퓨터에서는 30번 이동하므로 원이 도착하는 데 두 배의 시간이 걸립니다. F를 눌러 확인해 보세요. 게임이 초당 30프레임으로 실행되고 모든 움직임이 더 느려집니다.
해결 방법은 시간을 측정하는 것입니다. clock.tick()은 마지막 프레임 이후 경과한 밀리초를 반환합니다. 이를 1000으로 나누면 프레임의 길이를 초 단위로 나타내는 dt가 됩니다. 초당 60프레임에서는 약 0.017, 30프레임에서는 0.033입니다.
dt = 1 / 60 # 루프 전에
...
step = min(1, 6 * dt)
x += (target_x - x) * step
...
dt = clock.tick(fps) / 1000프레임이 길수록 이동 거리도 커지므로, 프레임 속도에 관계없이 같은 시간 동안 원은 같은 거리를 이동합니다. 6은 속도를 정합니다. 초당 60프레임에서 6 * dt는 약 0.1로, 이전과 같은 10분의 1입니다. min(1, ...)은 프레임이 매우 길어져 목표 지점을 지나치는 것을 방지합니다.
일반적인 이동도 마찬가지입니다. player_x += 240 * dt는 프레임 속도와 관계없이 초당 240픽셀 이동합니다. 대부분의 소규모 게임은 tick(60)으로 프레임 속도를 고정하므로 이 방법이 필요하지 않습니다. 프레임 속도가 달라질 수 있을 때는 dt를 사용하세요.
챌린지
중급F를 누르면 게임의 초당 프레임 수가 60과 30 사이에서 전환됩니다. 두 경우 모두 부드럽게 이동하는 데 같은 시간이 걸리도록 하세요:
- 루프 전에
dt = 1 / 60으로 설정합니다. - 루프 끝에서
dt = clock.tick(fps) / 1000으로 설정합니다. - 0.1 대신
step = min(1, 6 * dt)을 사용해 이동합니다:x += (target_x - x) * step으로 설정하고,y에도 똑같이 적용합니다.
직접 해보기
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Any Frame Rate")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 28)
x, y = 240, 180
target_x, target_y = 240, 180
fps = 60
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
target_x, target_y = event.pos
elif event.type == pygame.KEYDOWN and event.key == pygame.K_f:
fps = 30 if fps == 60 else 60
x += (target_x - x) * 0.1
y += (target_y - y) * 0.1
screen.fill((30, 30, 46))
pygame.draw.circle(screen, (80, 200, 220), (x, y), 12)
label = font.render(f"{fps} FPS (F to change)", True, (240, 240, 240))
screen.blit(label, (10, 10))
pygame.display.flip()
clock.tick(fps)
pygame.quit()
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
사운드와 게임의 손맛의 모든 레슨
직접 연습해 보세요: Pygame 플레이그라운드