Menu
CoddyTech

用时间驱动动画

本课属于 Coddy Pygame 学习旅程的“精灵与图像”单元。第 28 课,共 39 课。

帧计数器会让动画与帧率绑定。如果电脑每秒只能处理 30 帧,虫子的翅膀就会以一半的速度扇动。改为让动画与时间绑定。

pygame.time.get_ticks() 是自 pygame.init() 以来经过的毫秒数。除以每张图片应显示的时长,就能得到已经播放过的图片数量;% 会将其转换为索引:

frame_index = pygame.time.get_ticks() // 120 % len(frames)

从 0 到 119 ms 时显示图片 0,从 120 到 239 ms 时显示图片 1,然后是图片 2,再回到图片 0。不需要维护和重置计数器:只用一行代码,每帧都重新计算。如果游戏变慢,动画会跳过一张图片,而不是跟着变慢。

// 会执行除法并舍去余数:250 // 120 的结果是 2。这张精灵图的第三行包含一只飞行中的虫子的三个姿势,位于第 6 到第 8 列,已经切分到 frames 中。

challenge icon

挑战

中等

根据时钟为 bug 添加动画。

  1. 移除 timer 和计数器。
  2. 每一帧都根据 pygame.time.get_ticks() 设置 frame_index,让三张图片依次显示 120 毫秒。

按“开始”:bug 会扇动翅膀。然后按“检查”。

亲手试试

import pygame

pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Flying Bug")
clock = pygame.time.Clock()

sheet = pygame.image.load("assets/sheets/platformer_characters.png").convert_alpha()
frames = []
for col in (6, 7, 8):
    frame = sheet.subsurface((col * 24, 48, 24, 24))
    frames.append(pygame.transform.scale_by(frame, 3))
frame_index = 0
timer = 0

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

    timer += 1
    if timer == 10:
        timer = 0
        frame_index = (frame_index + 1) % len(frames)

    screen.fill((20, 22, 40))
    image = frames[frame_index]
    screen.blit(image, image.get_rect(center=(320, 240)))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

精灵与图像中的所有课

自己练习: Pygame 在线编辑器