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

Анимации — это душа любой игры. Когда несколько объектов движутся не синхронно, а с небольшим смещением по времени, это создает эффект волны или каскада, который оживляет сцену. В Phaser реализовать такой эффект проще простого с помощью встроенной функции `stagger`. Эта статья покажет, как использовать задержку для создания плавных и визуально привлекательных последовательных анимаций, что особенно полезно для меню, интерфейсов или групповых движений врагов.

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

    create ()
    {
        this.add.image(400, 300, 'bg');

        const image1 = this.add.image(100, 100, 'block').setScale(0.4);
        const image2 = this.add.image(100, 200, 'block').setScale(0.4);
        const image3 = this.add.image(100, 300, 'block').setScale(0.4);
        const image4 = this.add.image(100, 400, 'block').setScale(0.4);
        const image5 = this.add.image(100, 500, 'block').setScale(0.4);

        this.tweens.add({
            targets: [ image1, image2, image3, image4, image5 ],
            x: 700,
            yoyo: true,
            duration: 2000,
            ease: 'Sine.easeInOut',
            repeat: -1,
            delay: this.tweens.stagger(100)
        });
    }
}

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

const game = new Phaser.Game(config);

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

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

Мы загружаем фон и спрайт блока. Обратите внимание на использование setBaseURL для удобства указания пути к ресурсам.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('bg', 'assets/skies/sunset.png');
    this.load.image('block', 'assets/sprites/block-ice.png');
}

Создание объектов-целей для анимации

В методе create мы сначала добавляем фоновое изображение. Затем создаем пять спрайтов — наши будущие анимируемые цели. Мы позиционируем их вертикально и немного уменьшаем масштаб для лучшего визуального восприятия.

create ()
{
    this.add.image(400, 300, 'bg');

    const image1 = this.add.image(100, 100, 'block').setScale(0.4);
    const image2 = this.add.image(100, 200, 'block').setScale(0.4);
    const image3 = this.add.image(100, 300, 'block').setScale(0.4);
    const image4 = this.add.image(100, 400, 'block').setScale(0.4);
    const image5 = this.add.image(100, 500, 'block').setScale(0.4);
    ...
}

Магия функции stagger в твинах

Это ключевой момент. Мы создаем твин с помощью this.tweens.add. В качестве targets передаем массив всех пяти изображений. Твин будет двигать их по оси X, использовать эффект yoyo (возврат в исходную точку) и повторяться бесконечно.

Секрет каскадного эффекта кроется в параметре delay. Вместо статической задержки мы используем функцию this.tweens.stagger(100). Эта функция автоматически рассчитает задержку для каждого элемента в массиве targets. Первый элемент начнет движение сразу, второй — через 100 мс, третий — через 200 мс, и так далее.

this.tweens.add({
    targets: [ image1, image2, image3, image4, image5 ],
    x: 700,
    yoyo: true,
    duration: 2000,
    ease: 'Sine.easeInOut',
    repeat: -1,
    delay: this.tweens.stagger(100) // Каскадная задержка 100 мс между объектами
});

Настройка конфигурации игры

Здесь определяется базовая конфигурация игрового экземпляра Phaser. Указывается тип рендерера, размеры холста, цвет фона (который будет виден до загрузки ресурсов), родительский HTML-элемент и главная сцена.

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

const game = new Phaser.Game(config);

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

Функция stagger — это мощный и элегантный инструмент для создания сложных на вид анимаций с минимальным кодом. Она избавляет от необходимости вручную прописывать задержки для каждого объекта. Для экспериментов попробуйте изменить значение задержки в stagger, чтобы ускорить или замедлить волну. Поиграйте с другими параметрами твина: например, используйте stagger для свойств scale или angle, чтобы создать эффект последовательного увеличения или вращения группы спрайтов. Это отличный способ добавить полировку вашим игровым интерфейсам и визуальным эффектам.