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

Анимированные цепочки частиц, плавно движущиеся по сложным траекториям, — это мощный инструмент для создания визуальных эффектов в играх: от магических аура и следов за снарядами до интерфейсной анимации. В этом примере мы разберем, как использовать систему следования (`Follower`) и кривые (`Curves`) в Phaser 3 для создания гипнотического шлейфа из искр, циклично движущегося по заданному маршруту. Вы научитесь создавать плавные, повторяющиеся и задержанные анимации без единой строки Tween-кода вручную.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('sparkle', 'assets/particles/sparkle1.png');
    }

    create ()
    {
        const points = [
            50, 300, 179, 449, 394, 498, 593, 455,
            701, 338, 692, 190, 603, 76, 423, 41,
            272, 78, 181, 186, 230, 328, 416, 395,
            565, 327, 550, 202, 467, 149, 355, 164,
            343, 254, 428, 303
        ];

        const curve = new Phaser.Curves.Spline(points);

        for (let i = 0; i < 20; i++)
        {
            const follower = this.add.follower(curve, 100, 100 + (30 * i), 'sparkle');

            follower.setBlendMode(Phaser.BlendModes.ADD);

            follower.startFollow({
                duration: 4500,
                yoyo: true,
                repeat: -1,
                ease: 'Sine.easeInOut',
                _delay: i * 200,
                delay: i * 100
            });
        }
    }
}

const config = {
    type: Phaser.AUTO,
    width: 1024,
    height: 768,
    backgroundColor: '#000000',
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

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

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

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('sparkle', 'assets/particles/sparkle1.png');
}

Создание кривой пути

Вся траектория движения определяется массивом точек и объектом кривой. Phaser предоставляет класс Phaser.Curves.Spline, который создает плавную кривую, проходящую через все заданные точки. Это идеально для создания органичных, нелинейных путей.

Массив points содержит пары координат X и Y. Кривая строится последовательно от первой пары к последней.

const points = [
    50, 300, 179, 449, 394, 498, 593, 455,
    701, 338, 692, 190, 603, 76, 423, 41,
    272, 78, 181, 186, 230, 328, 416, 395,
    565, 327, 550, 202, 467, 149, 355, 164,
    343, 254, 428, 303
];

const curve = new Phaser.Curves.Spline(points);

Создание цепочки следящих объектов (Followers)

Основная магия происходит с помощью фабричного метода this.add.follower. Он создает игровой объект, который автоматически будет перемещаться по заданной кривой. Мы создаем 20 таких объектов, располагая их начальную позицию с небольшим вертикальным смещением.

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

for (let i = 0; i < 20; i++)
{
    const follower = this.add.follower(curve, 100, 100 + (30 * i), 'sparkle');
    follower.setBlendMode(Phaser.BlendModes.ADD);
}

Запуск анимации следования с параметрами

Чтобы объект начал движение, необходимо вызвать метод startFollow. Он принимает объект конфигурации, который гибко настраивает анимацию. Давайте разберем ключевые параметры, использованные в примере: - duration: Общее время прохождения всей кривой (в миллисекундах). - yoyo: Если true, объект, дойдя до конца кривой, пойдет обратно по тому же пути. - repeat: Количество повторений (-1 для бесконечного повторения). - ease: Функция плавности ('Sine.easeInOut' для плавного разгона и замедления). - delay: Задержка *перед началом* движения для каждого конкретного объекта. Именно этот параметр создает эффект "шлейфа" или "гусеницы".

Важно отметить наличие параметра _delay в коде примера. В официальной документации Phaser 3 такого параметра нет. Вероятно, это опечатка или устаревший параметр. Рабочим и корректным является параметр delay.

follower.startFollow({
    duration: 4500,
    yoyo: true,
    repeat: -1,
    ease: 'Sine.easeInOut',
    delay: i * 100 // Задержка для i-го объекта. Первый стартует сразу, последний — через 1900 мс.
});

Комбинация yoyo: true, repeat: -1 и ease: 'Sine.easeInOut' создает бесконечное плавное движение вперед-назад по кривой.

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

Используя связку Phaser.Curves и Follower, вы можете легко анимировать любые игровые объекты по заранее определенным сложным маршрутам, что открывает огромные возможности для визуального дизайна. Для экспериментов попробуйте: изменить форму кривой, добавив или убрав точки; использовать другую текстуру для частиц (например, стрелку или символ); заменить аддитивное смешивание на обычное (BlendModes.NORMAL) или на режим умножения (BlendModes.MULTIPLY); настроить параметры duration и delay для создания более резкого или, наоборот, более плавного шлейфа.