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

Создание систем частиц — ключ к визуальному богатству игры. Часто нужно, чтобы не просто частицы летели, а чтобы вся система частиц как единый объект плавно меняла прозрачность или перемещалась, создавая сложные эффекты исчезновения, появления или трансформации. В этом примере показано, как использовать мощь системы Tween для анимации самого Particle Emitter, а не отдельных частиц. Это простой и эффективный способ добавить слой динамики к визуальным эффектам без написания сложной логики обновления вручную.

Версия 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_25',
            speedX: { min: -300, max: 300 },
            speedY: { min: -300, max: 300 },
            lifespan: 2000,
            alpha: 1,
            scale: 0.5
        });

        this.tweens.add({
            targets: emitter,
            alpha: 0,
            y: 500,
            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 мы загружаем два изображения: фоновое небо (bg) и атлас спрайтов для частиц (match3). Атлас — это единое изображение, содержащее множество кадров (спрайтов), что оптимизирует загрузку и производительность.

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.

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

Далее мы создаем эмиттер частиц. Ключевой метод здесь — this.add.particles. Первые два аргумента (400, 100) задают начальную позицию эмиттера на сцене. Третий аргумент указывает на текстуру, а четвертый — это объект конфигурации для самих частиц.

const emitter = this.add.particles(400, 100, 'match3', {
    frame: 'Match3_Icon_25', // Конкретный кадр из атласа для частиц
    speedX: { min: -300, max: 300 }, // Случайная горизонтальная скорость
    speedY: { min: -300, max: 300 }, // Случайная вертикальная скорость
    lifespan: 2000, // Время жизни частицы в миллисекундах
    alpha: 1, // Начальная непрозрачность частиц (1 = полностью видима)
    scale: 0.5 // Масштаб частиц
});

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

Анимация эмиттера с помощью Tween

Самая интересная часть примера — анимация свойств самого объекта emitter. Мы используем менеджер this.tweens.add. Целью анимации (targets) является не частица, а эмиттер.

this.tweens.add({
    targets: emitter, // Цель — объект эмиттера частиц
    alpha: 0,        // Конечное значение прозрачности (полное исчезновение)
    y: 500,          // Конечная позиция по оси Y
    duration: 1500,  // Длительность одного цикла анимации в мс
    ease: 'sine.inout', // Функция плавности (плавное ускорение и замедление)
    yoyo: true,      // Анимация проигрывается в обратном порядке после завершения
    repeat: -1       // Бесконечное повторение
});

Tween плавно меняет свойства alpha (прозрачность) и `y(вертикальная позиция) объектаemitterв течение 1.5 секунд. Из-за флаговyoyoиrepeat` эмиттер будет постоянно «пульсировать» по вертикали между точками Y=100 и Y=500, одновременно плавно исчезая и появляясь. Это влияет на все испускаемые частицы как на единое целое.

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

Финальный шаг — стандартная конфигурация экземпляра игры Phaser.Game. Мы задаем тип рендерера, размеры холста, цвет фона, ID родительского HTML-элемента и стартовую сцену.

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

const game = new Phaser.Game(config);

После создания объекта game Phaser автоматически запускает жизненный цикл сцены Example.

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

Комбинируя систему частиц и Tween, вы получаете мощный инструмент для создания сложных визуальных последовательностей с минимальным кодом. Для экспериментов попробуйте: анимировать другие свойства эмиттера, такие как scale или angle; создать цепочку Tween для последовательного движения по пути; или сделать так, чтобы параметры частиц (например, lifespan) тоже менялись в зависимости от состояния эмиттера, используя события Tween.