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

Визуальные эффекты — важная часть игровой атмосферы. Частицы, вылетающие по форме звезды или по контуру прямоугольника, могут оживить любой проект. Этот пример демонстрирует, как использовать геометрические фигуры 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/skies/darkstone.png');
        this.load.atlas('flares', 'assets/particles/flares.png', 'assets/particles/flares.json');
    }

    create ()
    {
        const shape1 = new Phaser.Geom.Circle(0, 0, 160);
        const shape2 = new Phaser.Geom.Ellipse(0, 0, 500, 150);
        const shape3 = new Phaser.Geom.Rectangle(-150, -150, 300, 300);
        const shape4 = new Phaser.Geom.Line(-150, -150, 150, 150);
        const shape5 = new Phaser.Geom.Triangle.BuildEquilateral(0, -140, 300);

        const emitter = this.add.particles(400, 300, 'flares', {
            frame: { frames: [ 'red', 'green', 'blue' ], cycle: true },
            blendMode: 'ADD',
            lifespan: 500,
            scale: { start: 0.5, end: 0.1 }
        });

        emitter.addEmitZone({ type: 'edge', source: shape1, quantity: 32, total: 64 });
        emitter.addEmitZone({ type: 'edge', source: shape2, quantity: 32, total: 64 });
        emitter.addEmitZone({ type: 'edge', source: shape3, quantity: 32, total: 64 });
        emitter.addEmitZone({ type: 'edge', source: shape4, quantity: 32, total: 64 });
        emitter.addEmitZone({ type: 'edge', source: shape5, quantity: 32, total: 64 });
    }
}

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

const game = new Phaser.Game(config);

Основы работы с зонами эмиссии

В Phaser Particle Emitter может испускать частицы не только из случайной точки, но и из специально заданной зоны. Метод emitter.addEmitZone() добавляет такую зону в эмиттер. Ключевой параметр type: 'edge' указывает, что частицы должны появляться на границе (ребре) геометрической фигуры, а не заполнять её площадь.

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

Подготовка геометрических фигур

Перед созданием эмиттера в методе create() определяются пять различных геометрических фигур с центром в точке (0, 0). Это удобно, так как позже эмиттер будет позиционирован в центре экрана, и все фигуры будут отрисованы относительно него.

const shape1 = new Phaser.Geom.Circle(0, 0, 160);
const shape2 = new Phaser.Geom.Ellipse(0, 0, 500, 150);
const shape3 = new Phaser.Geom.Rectangle(-150, -150, 300, 300);
const shape4 = new Phaser.Geom.Line(-150, -150, 150, 150);
const shape5 = new Phaser.Geom.Triangle.BuildEquilateral(0, -140, 300);

Здесь создаются круг, эллипс, прямоугольник, линия и равносторонний треугольник. Обратите внимание на Phaser.Geom.Triangle.BuildEquilateral: это статический метод-хелпер для удобного построения правильного треугольника, где задаются координаты верхней вершины и длина стороны.

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

Эмиттер создаётся через фабрику this.add.particles(). Первые два аргумента (400, 300) — это координаты X и Y его позиции в мире. Третий аргумент — ключ атласа частиц 'flares', загруженного в preload().

const emitter = this.add.particles(400, 300, 'flares', {
    frame: { frames: [ 'red', 'green', 'blue' ], cycle: true },
    blendMode: 'ADD',
    lifespan: 500,
    scale: { start: 0.5, end: 0.1 }
});

В конфигурационном объекте: - frame: задаёт кадры из атласа, которые будут использоваться. Частицы будут циклически (cycle: true) брать один из трёх цветов: красный, зелёный, синий. - blendMode: 'ADD' — режим наложения, при котором цвета частиц складываются, создавая яркие светящиеся эффекты. - lifespan: 500 — время жизни каждой частицы в миллисекундах. - scale — объект, управляющий размером: частица стартует с масштаба 0.5 и к концу жизни уменьшается до 0.1.

Добавление зон эмиссии с лимитом total

Самый важный этап — подключение подготовленных фигур в качестве источников для испускания частиц. Для каждой фигуры вызывается emitter.addEmitZone() с конфигурацией.

emitter.addEmitZone({ type: 'edge', source: shape1, quantity: 32, total: 64 });
emitter.addEmitZone({ type: 'edge', source: shape2, quantity: 32, total: 64 });
// ... и так для всех пяти фигур

Параметры зоны: - type: 'edge': Частицы появляются строго на границе фигуры. - source: Геометрическая фигура, которая была создана ранее. - quantity: 32: Количество частиц, испускаемых за один вызов эмиттера. В данном примере эмиттер, судя по всему, работает в непрерывном режиме, поэтому это параметр циклического испускания. - total: 64: Критически важный параметр. Он устанавливает общий лимит частиц, которые могут быть испущены ИЗ ЭТОЙ КОНКРЕТНОЙ ЗОНЫ. Как только количество испущенных частиц достигает 64, эта зона перестаёт работать. Именно поэтому в демо-примере частицы из каждой фигуры испускаются лишь некоторое время, а затем эффект затухает, создавая динамичную, не вечно повторяющуюся картину.

Практическое применение и контроль

Использование параметра total даёт разработчику мощный инструмент для создания непериодических, управляемых по времени эффектов. Например: 1. **Однократный эффект:** Установите total равным quantity, и зона испустит частицы всего один раз. 2. **Последовательность эффектов:** Добавляя несколько зон с разным total, можно создать каскад, где одна фигура затухает, а другая начинает светиться. 3. **Ресурс-ориентированные эффекты:** Параметр total предотвращает бесконечное испускание, что полезно для эффектов с ограниченным «зарядом», например, расходуемого зелья или разового заклинания.

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

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

Сочетание геометрических фигур Phaser и системы частиц с параметром total позволяет создавать сложные, управляемые по времени визуальные эффекты. Вы можете точно контролировать, сколько частиц и из какой формы будет испущено, что невозможно при использовании случайного разброса. Для экспериментов попробуйте: изменить тип зоны с 'edge' на 'random' для заполнения площади фигуры; анимировать саму фигуру-источник, перемещая её вершины, чтобы эффект «двигался»; или привязать сброс счетчика total к игровому событию, чтобы перезаряжать эффект.