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

При создании визуальных эффектов, таких как огонь, дым или магические вспышки, часто нужно, чтобы частицы исчезали при столкновении с объектами мира, а не просто по истечении времени жизни. Механика Death Zones (зон смерти) в системе частиц Phaser 3 позволяет реализовать это элегантно и с минимальным кодом. В этой статье мы разберем готовый пример, где частицы гаснут, попадая в определенные прямоугольные области. Вы научитесь создавать такие зоны, визуализировать их для отладки и динамически управлять источником частиц.

Версия 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 параметр deathZone принимает массив объектов, реализующих интерфейс Phaser.Types.GameObjects.Particles.DeathZone. Эти объекты определяют область, при пересечении которой частица немедленно уничтожается.

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

deathZone: [ rect1, rect2, rect3 ]

Создание эмиттера и определение зон

В методе create() сцены сначала создаются три прямоугольника, которые будут нашими зонами смерти. Их координаты и размеры задаются в пикселях.

Затем создается сам эмиттер частиц. Ключевые параметры: * frame: определяет, какие текстуры из атласа 'flares' будут использоваться (красный, зеленый, синий). * speed и gravityY: задают физику движения частиц. * deathZone: принимает массив созданных прямоугольников.

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 ]
});

Динамическое перемещение источника

Пример делает систему интерактивной. При клике мышью (pointerdown) позиция эмиттера переопределяется. Это позволяет "стрелять" потоком частиц из разных точек экрана и наблюдать, как они исчезают в заданных зонах.

Метод setPosition эмиттера принимает мировые координаты (worldX, worldY), которые автоматически предоставляет объект события pointer.

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

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

Чтобы видеть, где именно расположены невидимые зоны смерти, их нужно нарисовать. Для этого создается объект Graphics.

С помощью lineStyle задается стиль линии (толщина, цвет, альфа), а strokeRectShape рисует контур каждого прямоугольника. Это необязательный, но крайне полезный шаг на этапе отладки и настройки сцены.

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

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

Death Zones — мощный и простой инструмент для тонкого контроля над жизненным циклом частиц. Они идеально подходят для создания эффектов взаимодействия: например, дождь, который не проходит сквозь крышу, или искры, гаснущие в воде. Для экспериментов попробуйте: 1. Заменить прямоугольные зоны на круглые (Phaser.Geom.Circle). 2. Сделать зоны динамическими — перемещать их в реальном времени вместе с игровыми объектами. 3. Использовать обратные зоны (с флагом killOnEnter: false), чтобы частицы, наоборот, выживали только внутри определенной области.