О чем этот пример
Анимации в игровых движках часто требуют не просто перемещения объекта, но и изменения его внешнего вида для создания более динамичных сцен. Встроенный менеджер Tween в Phaser 3 позволяет не только анимировать свойства вроде позиции, но и управлять визуальными эффектами, такими как отражение спрайта. В этой статье мы разберем, как с помощью простой конфигурации твина заставить игровой объект не только двигаться по траектории "йо-йо", но и зеркально отражаться по вертикали в обратном направлении, что полезно для создания иллюзии разворота или более плавного циклического движения.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('bg', 'assets/tweens/grass.png');
this.load.image('road', 'assets/tweens/track.png');
this.load.image('car', 'assets/tweens/f1car.png');
}
create ()
{
this.add.image(400, 300, 'bg');
this.add.image(400, 300, 'road');
const car = this.add.image(270, 1000, 'car');
// The `flipY: true` in the Tween config will force the Image
// to be vertically flipped when the Tween yoyos or repeats
this.tweens.add({
targets: car,
y: -400,
flipY: true,
yoyo: true,
duration: 2000,
repeat: -1
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и загрузка ресурсов
Класс Example расширяет Phaser.Scene и содержит стандартные методы жизненного цикла. В preload мы загружаем три изображения, используя базовый URL репозитория с примерами. Обратите внимание: this.load.setBaseURL задает корневой путь, что позволяет указывать относительные пути для ассетов.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('bg', 'assets/tweens/grass.png');
this.load.image('road', 'assets/tweens/track.png');
this.load.image('car', 'assets/tweens/f1car.png');
В методе create сначала добавляются фоновые изображения (bg и road) в центр экрана с координатами (400, 300). Затем создается основной объект для анимации — изображение машины (car). Изначально оно позиционируется за нижней границей экрана по оси Y (значение 1000), что создает исходную точку для будущего движения.
Создание и настройка Tween-анимации
Ключевая часть кода — создание твина через this.tweens.add. Конфигурационный объект передается этому методу. Давайте разберем его свойства.
this.tweens.add({
targets: car,
y: -400,
flipY: true,
yoyo: true,
duration: 2000,
repeat: -1
});
* targets: car — указывает, к какому объекту (или массиву объектов) будет применена анимация.
* y: -400 — целевое значение свойства `y` (позиция по вертикали). Объект будет двигаться от начального Y=1000 до Y=-400 (далеко за верхней границей экрана).
* flipY: true — **важнейший параметр**. Он указывает твину автоматически переключать свойство flipY изображения, когда анимация начинает движение в обратном направлении (из-за режима yoyo или при повторении). Это визуальное отражение по вертикали.
* yoyo: true — включает режим "йо-йо". После достижения конечной точки (y: -400) анимация автоматически проигрывается в обратном порядке до начального состояния.
* duration: 2000 — длительность одного направления анимации в миллисекундах (2 секунды от начала до точки y: -400). В режиме yoyo полный цикл (туда-обратно) займет 4 секунды.
* repeat: -1 — задает бесконечное повторение всей анимации (включая фазы "йо-йо").
Как работает свойство `flipY` в контексте Tween
Свойство flipY объекта Image (и любого другого Game Object) по умолчанию имеет значение false. При установке в true изображение отражается по вертикали (переворачивается "вверх ногами").
Магия твина заключается в том, что когда вы задаете flipY: true в его конфигурации, он **не просто устанавливает это свойство один раз**. Вместо этого он интеллектуально связывает переключение этого флага с изменением направления анимации. Когда объект движется к цели (y: -400), flipY равно false (исходное состояние). Как только цель достигнута и активируется фаза "йо-йо" (движение обратно к начальной точке), твин автоматически меняет flipY на true. При следующем цикле (снова к цели) он вернет flipY в false.
Это создает эффект, будто машина не просто едет вперед-назад, а **разворачивается** в конечных точках маршрута, что выглядит гораздо более естественно для циклической анимации, чем просто движение назад тем же "боком".
Конфигурация и запуск игры
Сцена готова, осталось создать экземпляр игры Phaser.Game, передав ему объект конфигурации. Здесь задаются базовые параметры отображения.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
* type: Phaser.AUTO — позволяет Phaser'у самому выбрать рендерер (WebGL или Canvas).
* width и height — устанавливают размер игрового поля.
* backgroundColor — цвет фона, который будет виден, пока загружаются ассеты или если они не покрывают весь экран.
* parent: 'phaser-example' — ID HTML-элемента, в который будет встроен canvas игры.
* scene: Example — указывает, что экземпляр нашего класса Example будет использован как начальная сцена.
Что попробовать дальше
Использование свойства flipY (и его горизонтального аналога flipX) в конфигурации твина — это мощный и лаконичный способ добавить визуальную динамику циклическим анимациям. Phaser берет на себя управление переключением этого свойства, синхронизируя его с направлением движения. Для экспериментов попробуйте:
1. Заменить flipY: true на flipX: true, чтобы машина отражалась горизонтально, создавая иллюзию разворота на 180 градусов.
2. Скомбинировать оба свойства: flipX: true, flipY: true для более сложного визуального эффекта.
3. Поиграть с другими свойствами, которые можно анимировать вместе с движением, например angle или scale, чтобы создать анимацию подпрыгивающего и переворачивающегося объекта.
