О чем этот пример

Анимации в игровых движках часто требуют не просто перемещения объекта, но и изменения его внешнего вида для создания более динамичных сцен. Встроенный менеджер 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, чтобы создать анимацию подпрыгивающего и переворачивающегося объекта.