Спрайтовая анимация: кадры и спрайт-лист
Анимация — это быстрая смена кадров одного изображения по собственному таймеру, не совпадающему с частотой кадров игры.
До сих пор персонажи были статичными фигурами или одной неподвижной картинкой. Анимация — это быстрая смена нескольких кадров рисунка, создающая иллюзию движения, — тот же принцип, что и в мультфильме или флипбуке.
Спрайт-лист
Спрайт-лист (sprite sheet) — одно изображение, в котором кадры анимации выложены в ряд.
Чтобы показать нужный кадр, из общего изображения вырезается прямоугольная область через
subsurface():
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 смен рисунка в секунду). Вместо этого копится время в накопителе (аккумуляторе), и кадр анимации переключается по своему собственному, более медленному таймеру:
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 существует именно для того, чтобы избежать подобной рассинхронизации на один кадр.