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

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

Версия 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.atlas('flares', 'assets/particles/flares.png', 'assets/particles/flares.json');
    }

    create ()
    {
        const rect1 = new Phaser.Geom.Rectangle(100, 50, 100, 100);
        const rect2 = new Phaser.Geom.Rectangle(200, 350, 400, 200);
        const rect3 = new Phaser.Geom.Rectangle(550, 150, 200, 100);

        const emitter = this.add.particles(400, 100, 'flares', {
            frame: [ 'red', 'green', 'blue' ],
            speed: 300,
            gravityY: 400,
            lifespan: 4000,
            scale: 0.4,
            blendMode: 'ADD',
            deathZone: [ rect1, rect2, rect3 ]
        });

        this.input.on('pointerdown', pointer => {

            emitter.setPosition(pointer.worldX, pointer.worldY);

        });

        const graphics = this.add.graphics();

        graphics.lineStyle(1, 0x00ff00, 1);

        graphics.strokeRectShape(rect1);
        graphics.strokeRectShape(rect2);
        graphics.strokeRectShape(rect3);
    }
}

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

const game = new Phaser.Game(config);

Что такое смертельная зона (death zone)?

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

В примере используются три прямоугольные зоны (Phaser.Geom.Rectangle), которые передаются в конфигурацию эмиттера через параметр deathZone. Зоны определяются координатами (x, y), шириной и высотой.

const rect1 = new Phaser.Geom.Rectangle(100, 50, 100, 100);
const rect2 = new Phaser.Geom.Rectangle(200, 350, 400, 200);
const rect3 = new Phaser.Geom.Rectangle(550, 150, 200, 100);

Настройка эмиттера частиц

Эмиттер создаётся с помощью метода this.add.particles. В примере он настроен на использование атласа 'flares' с кадрами 'red', 'green' и 'blue'. Частицы вылетают с начальной скоростью 300 пикселей в секунду, имеют гравитацию по оси Y (400), время жизни 4 секунды и масштаб 0.4. Режим смешивания 'ADD' делает цвета более яркими при наложении.

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

const emitter = this.add.particles(400, 100, 'flares', {
    frame: [ 'red', 'green', 'blue' ],
    speed: 300,
    gravityY: 400,
    lifespan: 4000,
    scale: 0.4,
    blendMode: 'ADD',
    deathZone: [ rect1, rect2, rect3 ]
});

Динамическое управление эмиттером

Пример добавляет интерактивность: при клике мышью позиция эмиттера меняется на координаты указателя. Это демонстрирует, как смертельные зоны работают в реальном времени — частицы начинают вылетать из новой точки, но всё также исчезают при попадании в зоны.

Метод emitter.setPosition() обновляет координаты источника частиц. pointer.worldX и pointer.worldY предоставляют глобальные координаты клика в игровом мире.

this.input.on('pointerdown', pointer => {
    emitter.setPosition(pointer.worldX, pointer.worldY);
});

Визуализация зон для отладки

Чтобы видеть смертельные зоны на экране, пример использует графический объект (graphics). С помощью graphics.lineStyle() задаётся стиль линии: толщина 1, зелёный цвет (0x00ff00) и непрозрачность 1. Затем метод graphics.strokeRectShape() рисует контуры всех трёх прямоугольников.

Это особенно полезно при разработке, чтобы точно размещать зоны и проверять их взаимодействие с частицами.

const graphics = this.add.graphics();
graphics.lineStyle(1, 0x00ff00, 1);
graphics.strokeRectShape(rect1);
graphics.strokeRectShape(rect2);
graphics.strokeRectShape(rect3);

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

Смертельные зоны в Phaser — мощный инструмент для контроля жизненного цикла частиц. Они позволяют создавать сложные эффекты, такие как исчезновение частиц при контакте с объектами или ограничение их распространения. Для экспериментов попробуйте изменить форму зон (например, используйте Phaser.Geom.Circle), добавить анимацию их перемещения или комбинировать смертельные зоны с другими типами зон, например, emitZone (зоной испускания). Это откроет новые возможности для визуального дизайна вашей игры.