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

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

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

Живой запуск

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

Исходный код


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

    create ()
    {
        const particles = this.add.particles('flares');

        particles.createEmitter({
            frame: { frames: [ 'red', 'blue', 'green', 'yellow' ], cycle: true },
            x: 400,
            y: { start: 0, end: 632, steps: 32 },
            lifespan: 2000,
            accelerationX: 300,
            scale: 0.5,
            blendMode: 'ADD'
        });

        particles.createEmitter({
            frame: { frames: [ 'red', 'blue', 'green', 'yellow' ], cycle: true },
            x: 400,
            y: { start: 600, end: -32, steps: 32 },
            lifespan: 2000,
            accelerationX: -300,
            scale: 0.5,
            blendMode: 'ADD'
        });
    }
}

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

const game = new Phaser.Game(config);

Разбираем структуру сцены

Пример построен по классической схеме сцены Phaser. Ключевые этапы — предзагрузка ассетов (preload) и их использование при создании сцены (create).

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

В методе preload мы задаем базовый URL для загрузки и загружаем атлас частиц 'flares'. Атлас — это изображение (спрайтшит), содержащее несколько кадров (текстур) для частиц, и JSON-файл с их координатами. Использование атласа эффективнее загрузки множества отдельных изображений.

Создание менеджера и первого эмиттера

В методе create мы создаем систему частиц и первый эмиттер, который испускает частицы слева направо.

create ()
{
    const particles = this.add.particles('flares');

    particles.createEmitter({
        frame: { frames: [ 'red', 'blue', 'green', 'yellow' ], cycle: true },
        x: 400,
        y: { start: 0, end: 632, steps: 32 },
        lifespan: 2000,
        accelerationX: 300,
        scale: 0.5,
        blendMode: 'ADD'
    });

this.add.particles('flares') создает менеджер частиц, который будет использовать загруженный атлас. Метод createEmitter настраивает эмиттер. Разберем параметры: - frame: Частицы будут поочередно (cycle: true) брать текстуры 'red', 'blue', 'green', 'yellow' из атласа. - `x`: Фиксированная позиция по горизонтали в центре экрана (400px). - `y: Задает 32 точки испускания (steps: 32`) равномерно распределенные от верхнего края экрана (0) почти до нижнего (632). - lifespan: Время жизни частицы в миллисекундах (2000 мс = 2 сек). - accelerationX: Постоянное ускорение по оси X. Положительное значение (300) двигает частицы вправо. - scale: Масштаб частицы (0.5 — половина исходного размера). - blendMode: Режим наложения 'ADD' делает частицы яркими и светящимися при наложении.

Второй эмиттер и зеркальный эффект

Вторая часть эффекта создается почти идентичным эмиттером, но с ключевыми отличиями в параметрах движения.

particles.createEmitter({
        frame: { frames: [ 'red', 'blue', 'green', 'yellow' ], cycle: true },
        x: 400,
        y: { start: 600, end: -32, steps: 32 },
        lifespan: 2000,
        accelerationX: -300,
        scale: 0.5,
        blendMode: 'ADD'
    });
}

Здесь изменены два свойства: - `y`: Точки испускания теперь идут снизу вверх (от 600 до -32). Это создает зеркальное отражение первого потока. - accelerationX: Ускорение отрицательное (-300), что заставляет частицы двигаться влево.

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

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

Код завершается стандартной конфигурацией игры и ее инициализацией.

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

const game = new Phaser.Game(config);

Важные моменты конфига: - type: Phaser.WEBGL: Используется WebGL-рендерер, который необходим для корректной работы режима наложения blendMode: 'ADD'. - backgroundColor: '#000': Черный фон лучше всего контрастирует со светящимися частицами. - scene: Example: Указывает класс сцены, которая будет запущена первой.

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

Используя всего два эмиттера с противоположными векторами ускорения, мы создали сложный на вид визуальный эффект. Сила Phaser 3 — в простоте и выразительности его API для частиц. Для экспериментов попробуйте изменить параметры: замените accelerationX на accelerationY для вертикальных потоков, поиграйте со значениями lifespan и scale во времени, добавьте гравитацию (gravityY) или измените режим наложения на 'NORMAL'. Такой подход открывает путь к созданию огня, дыма, звёздных полей и магических аур.