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

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

Версия 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('bg', 'assets/tweens/sky.png');
        this.load.atlas('match3', 'assets/atlas/match3.png', 'assets/atlas/match3.json');
    }

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

        const emitter = this.add.particles(400, 100, 'match3', {
            frame: 'Match3_Icon_01',
            speedX: 200,
            lifespan: 2000,
            alpha: { start: 1, end: 0 },
            gravityY: 200,
            scale: 0.5
        });

        this.tweens.add({
            targets: emitter,
            speedX: -200,
            duration: 1500,
            ease: 'sine.inout',
            yoyo: true,
            repeat: -1
        });
    }
}

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

const game = new Phaser.Game(config);

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

В методе preload мы загружаем необходимые изображения. Обратите внимание на использование setBaseURL, который задаёт базовый путь для всех последующих загрузок — это удобно, если ваши ресурсы лежат в одной директории.

Загружается фон (bg) и атлас (match3). Атлас — это один файл изображения, содержащий несколько спрайтов (фреймов), и отдельный JSON-файл с их координатами. Использование атласов оптимизирует производительность.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('bg', 'assets/tweens/sky.png');
this.load.atlas('match3', 'assets/atlas/match3.png', 'assets/atlas/match3.json');

Создание эмиттера частиц

В методе create сначала добавляется фоновое изображение. Затем создаётся эмиттер частиц с помощью this.add.particles.

Ключевые параметры эмиттера: - speedX: 200 — начальная горизонтальная скорость частиц (вправо). - lifespan: 2000 — время жизни частицы в миллисекундах. - alpha: { start: 1, end: 0 } — частицы плавно исчезают. - gravityY: 200 — сила гравитации, притягивающая частицы вниз. - scale: 0.5 — масштаб частиц.

Эмиттер создаётся в точке (400, 100) и использует фрейм Match3_Icon_01 из загруженного атласа.

const emitter = this.add.particles(400, 100, 'match3', {
    frame: 'Match3_Icon_01',
    speedX: 200,
    lifespan: 2000,
    alpha: { start: 1, end: 0 },
    gravityY: 200,
    scale: 0.5
});

Анимация свойства speedX с помощью Tween

Здесь происходит самое интересное. Мы создаём твин, который будет анимировать свойство speedX самого объекта emitter.

Конфигурация твина: - targets: emitter — указываем, что анимируем эмиттер. - speedX: -200 — целевое значение свойства. Твин плавно изменит speedX с 200 до -200. - duration: 1500 — длительность одной анимации в миллисекундах. - ease: 'sine.inout' — функция плавности, создающая мягкое ускорение и замедление. - yoyo: true — после достижения цели анимация проиграется в обратном порядке. - repeat: -1 — анимация повторяется бесконечно.

В результате горизонтальная скорость всех частиц, испускаемых эмиттером, будет плавно колебаться между +200 (вправо) и -200 (влево), создавая эффект маятника или волны.

this.tweens.add({
    targets: emitter,
    speedX: -200,
    duration: 1500,
    ease: 'sine.inout',
    yoyo: true,
    repeat: -1
});

Конфигурация и запуск игры

Стандартная конфигурация игры Phaser. Указываем тип рендерера (AUTO), размеры холста, цвет фона и класс сцены, которая будет запущена первой.

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

const game = new Phaser.Game(config);

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

Использование твинов для анимации свойств эмиттера — мощный и простой способ добавить динамику системе частиц. Вы можете анимировать не только speedX, но и другие свойства, такие как speedY, angle, gravityX, scale или даже позицию самого эмиттера (`x,y`). **Идеи для экспериментов:** 1. Попробуйте анимировать свойство scale эмиттера, чтобы частицы то увеличивались, то уменьшались. 2. Создайте два эмиттера с разными настройками твинов и цветами для более сложного визуального эффекта. 3. Используйте событие onUpdate в твине, чтобы в реальном времени менять другие параметры системы (например, цвет) в зависимости от текущего значения speedX.