Глава 20 · Разработка игр с Pygame

Спрайтовая анимация: кадры и спрайт-лист

Анимация — это быстрая смена кадров одного изображения по собственному таймеру, не совпадающему с частотой кадров игры.

До сих пор персонажи были статичными фигурами или одной неподвижной картинкой. Анимация — это быстрая смена нескольких кадров рисунка, создающая иллюзию движения, — тот же принцип, что и в мультфильме или флипбуке.

Спрайт-лист

Спрайт-лист (sprite sheet) — одно изображение, в котором кадры анимации выложены в ряд. Чтобы показать нужный кадр, из общего изображения вырезается прямоугольная область через subsurface():

kadr_iz_lista.py
SHIRINA_KADRA, VYSOTA_KADRA = 32, 32
sprajt_list = pygame.image.load("assets/hodba.png").convert_alpha()

def poluchit_kadr(nomer):
    x = nomer * SHIRINA_KADRA
    return sprajt_list.subsurface((x, 0, SHIRINA_KADRA, VYSOTA_KADRA))

Таймер анимации

Кадры анимации не должны меняться каждый кадр игрового цикла — это слишком быстро (при 60 FPS это 60 смен рисунка в секунду). Вместо этого копится время в накопителе (аккумуляторе), и кадр анимации переключается по своему собственному, более медленному таймеру:

tajmer_animacii.py
INTERVAL_KADRA = 0.12   # секунд на один кадр анимации
tekushij_kadr = 0
vremya_animacii = 0.0

vremya_animacii += dt
while vremya_animacii >= INTERVAL_KADRA:
    vremya_animacii -= INTERVAL_KADRA
    tekushij_kadr = (tekushij_kadr + 1) % KOLICHESTVO_KADROV

% KOLICHESTVO_KADROV (остаток от деления, глава 4) заставляет счётчик кадра зациклиться: после последнего кадра анимация начинается заново с нулевого. Здесь важен именно while, а не if: если один игровой кадр из-за просадки FPS длится дольше, чем сразу несколько интервалов анимации, while переключит кадр анимации нужное число раз подряд и сохранит остаток времени в vremya_animacii для следующего прохода. if вместо этого продвинул бы анимацию только на один кадр и молча потерял лишнее накопленное время.

Четыре реальных окна рядом: у голубой фигурки нога от кадра к кадру смещается вправо, отмеряя шаг
Реальное окно: четыре кадра одной и той же простой анимации ходьбы, нарисованные вручную для этого примера — тот же принцип, что и у настоящего спрайт-листа.
Обновление после отрисовки — анимация отстаёт на кадр
Если код, который переключает tekushij_kadr, стоит после отрисовки текущего кадра, игрок на экране всегда видит предыдущее состояние анимации, а не только что вычисленное. Порядок Update → Render из раздела 20.14 существует именно для того, чтобы избежать подобной рассинхронизации на один кадр.
Практика: спрайт-лист и таймер анимации
Pygame открывает нативное окно Python — выполните локально в VS Code, PyCharm или Jupyter
Практика выполняется локально
Открыть практику →