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

Плавные и выразительные анимации — ключ к созданию живой игры. Phaser 3 предоставляет мощную систему твинов (tweens), которая позволяет анимировать любые свойства игрового объекта, такие как положение, прозрачность или масштаб. В этой статье мы разберем, как одной анимацией управлять движением спрайта по горизонтали с плавным ускорением и по вертикали с эффектом отскока, используя разные длительности и функции плавности для каждого свойства.

Версия 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('block', 'assets/sprites/block.png');
    }

    create ()
    {
        const image = this.add.image(100, 100, 'block');

        this.tweens.add({
            targets: image,
            x: { value: 700, duration: 4000, ease: 'Power2' },
            y: { value: 400, duration: 1500, ease: 'Bounce.easeOut' }
        });
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d',
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Подготовка сцены и загрузка спрайта

Как и в любом проекте на Phaser, начинаем с создания класса сцены, наследующего от Phaser.Scene. Ключевыми методами жизненного цикла являются preload() для загрузки ресурсов и create() для их создания и настройки логики.

В методе preload() мы загружаем спрайт. Обратите внимание на использование this.load.setBaseURL() — оно задает базовый путь для всех последующих загрузок, что упрощает указание относительных путей к файлам.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('block', 'assets/sprites/block.png');

В методе create() мы создаем игровой объект Image из загруженной текстуры и помещаем его в начальную точку с координатами (100, 100).

Создание составного твина

Сердце примера — вызов this.tweens.add(). Этот метод принимает объект конфигурации, который описывает анимацию.

Цель анимации задается в поле targets. В нашем случае это один объект image, но можно передать и массив объектов.

this.tweens.add({
    targets: image,
    x: { value: 700, duration: 4000, ease: 'Power2' },
    y: { value: 400, duration: 1500, ease: 'Bounce.easeOut' }
});

Особенность этого подхода в том, что свойства `xиy` заданы не простыми значениями, а конфигурационными объектами. Это позволяет независимо настраивать параметры анимации для каждой оси.

Настройка параметров для каждого свойства

Давайте детально разберем параметры, указанные для свойств `xиy`.

* value: Конечное значение свойства. Спрайт переместится из x=100 в x=700 и из y=100 в y=400. * duration: Длительность анимации этого конкретного свойства в миллисекундах. Анимация по оси X займет 4 секунды (4000 мс), а по оси Y — всего 1.5 секунды (1500 мс). Это значит, что вертикальное движение (отскок) завершится гораздо раньше, чем горизонтальное, после чего спрайт продолжит плавное движение вправо. * ease: Функция плавности (easing), определяющая характер движения. * Для `xиспользуется'Power2'`, что создает эффект плавного ускорения в начале и замедления в конце движения. * Для `yиспользуется'Bounce.easeOut'. Эта функция имитирует физику отскока, когда объект несколько раз «прыгает» у точки назначения, прежде чем остановиться. Суффикс.easeOut` указывает, что эффект применяется к концу анимации.

Именно разделение параметров позволяет создать сложную, составную анимацию одним твином.

Запуск игры: конфигурация и инстанс

Чтобы сцена заработала, необходимо создать основной объект игры Phaser.Game и передать ему конфигурацию. Конфигурация определяет базовые настройки рендерера и указывает, какую сцену использовать по умолчанию.

const config = {
    type: Phaser.AUTO, // Автовыбор между WebGL и Canvas
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d',
    parent: 'phaser-example', // ID HTML-элемента для вставки канваса
    scene: Example // Класс главной сцены
};

const game = new Phaser.Game(config);

После создания экземпляра game Phaser автоматически запускает жизненный цикл сцены: вызовет preload(), а затем create(), в котором и будет запущен наш твин.

Что попробовать дальше

Система твинов в Phaser 3 — это гибкий инструмент для создания сложных анимаций без написания кастомной логики на каждом кадре. Показанный подход с конфигурационными объектами для каждого свойства открывает путь к созданию выразительных и нетривиальных движений. Для экспериментов попробуйте

  1. добавить анимацию свойства scale для увеличения или уменьшения спрайта одновременно с движением
  2. изменить функцию плавности ease на 'Elastic' или 'Back' для других физических эффектов
  3. анимировать не `xиy, а свойстваangle(вращение) иalpha` (прозрачность)