В Phaser система анимации построена на разделении данных и поведения.
Глобальный менеджер анимаций хранит определения, а каждый отображаемый
объект (Sprite, Image с текстурой атласа и
др.) получает собственный компонент AnimationState,
отвечающий за проигрывание, переключение и управление текущим состоянием
анимации.
AnimationState — это не отдельный класс, который
создаётся вручную, а встроенный компонент, автоматически добавляемый к
объектам типа Phaser.GameObjects.Sprite. Он
инкапсулирует:
Внутри сцены (Scene) существует менеджер анимаций:
this.anims
Он хранит глобальные определения анимаций. Компонент
AnimationState конкретного спрайта обращается к этому
менеджеру при запуске:
sprite.play('run');
Происходит следующий процесс:
'run' ищется глобальное определение.AnimationState начинает управлять кадрами.Таким образом:
this.anims.create({
key: 'run',
frames: this.anims.generateFrameNumbers('player', {
start: 0,
end: 5
}),
frameRate: 10,
repeat: -1
});
player.play('run');
Метод play() принадлежит компоненту
AnimationState.
Компонент содержит ряд ключевых свойств:
currentAnimСсылка на текущую анимацию. Если равна null,
проигрывание отсутствует.
currentFrameОбъект текущего кадра.
isPlayingБулево значение, отражающее активное проигрывание.
isPausedПауза без сброса позиции.
progressНормализованное значение (0–1), отражающее прогресс проигрывания.
sprite.play('attack');
С перезапуском:
sprite.play('attack', true);
Второй аргумент ignoreIfPlaying предотвращает повторный
запуск.
sprite.anims.pause();
Возобновление:
sprite.anims.resume();
sprite.anims.stop();
Сброс к первому кадру:
sprite.anims.stop('run');
sprite.anims.setFrameRate(20);
sprite.anims.timeScale = 2;
timeScale умножает базовую скорость:
1 — нормальная скорость2 — в 2 раза быстрее0.5 — в 2 раза медленнееПри создании:
repeat: 3
Значения:
0 — один раз>0 — указанное количество повторений-1 — бесконечноsprite.anims.on('animationcomplete', callback);
Также возможно отследить конкретную анимацию:
sprite.on('animationcomplete-attack', callback);
AnimationState поддерживает очередь.
sprite.play('attack');
sprite.chain('idle');
После завершения attack автоматически начнётся
idle.
Также возможно:
sprite.anims.queue('idle');
AnimationState удобно использовать как часть логики конечного автомата (FSM).
Пример управления:
if (body.velocity.x !== 0) {
player.play('run', true);
} else {
player.play('idle', true);
}
Аргумент true предотвращает перезапуск при уже активной
анимации.
sprite.anims.reverse();
sprite.anims.playReverse('run');
sprite.anims.setCurrentFrame(
sprite.anims.currentAnim.frames[3]
);
Также доступно:
sprite.anims.setProgress(0.5);
Компонент генерирует ряд событий:
animationstartanimationupdateanimationrepeatanimationcompleteanimationstopПример:
sprite.on('animationstart', (anim) => {
console.log('Начало:', anim.key);
});
Помимо глобальных анимаций, AnimationState поддерживает
локальные.
sprite.anims.create({
key: 'localAnim',
frames: [...]
});
Такая анимация доступна только этому объекту.
При использовании физики (Arcade Physics) часто
требуется синхронизация движения и анимации.
if (player.body.velocity.y < 0) {
player.play('jump', true);
}
В Phaser обновление анимации происходит автоматически в цикле
Scene.update().
При создании:
repeat: 0,
hideOnComplete: false
Либо вручную:
sprite.on('animationcomplete', () => {
sprite.anims.stop();
});
Метод play() принимает объект:
sprite.anims.play({
key: 'attack',
frameRate: 30,
repeat: 2,
delay: 100
});
Это позволяет динамически менять поведение без пересоздания анимации.
enemy1.play('walk');
enemy2.play('walk');
Для точной синхронизации:
enemy2.anims.setProgress(enemy1.anims.progress);
sprite.anims.playAfterDelay('attack', 500);
Запуск через 500 мс.
В редких случаях требуется ручной контроль:
sprite.anims.update(time, delta);
Обычно не используется, так как система обновляется автоматически.
play() каждый кадр без
ignoreIfPlaying.chain() вместо логики через события при
последовательностях.update().AnimationState реализует изолированное управление
визуальным состоянием объекта:
Такое разделение соответствует компонентному подходу движка Phaser, где каждый аспект поведения инкапсулирован и управляется независимо.
В крупных проектах удобно выделять метод:
setState(state) {
if (this.state === state) return;
this.state = state;
this.play(state, true);
}
Это снижает количество условных операторов в update() и
делает логику читаемой.
AnimationState становится визуальным отражением
логического состояния:
Такой подход облегчает масштабирование проекта и поддержку кода.
Компонент анимации в Phaser — это полноценная подсистема управления временными состояниями спрайта, предоставляющая гибкий, событийный и высокопроизводительный механизм визуализации динамики игровых объектов.