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

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

Версия 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 ()
    {
        //  Any particles that enter this shape will be killed instantly
        const rect = new Phaser.Geom.Rectangle(200, 350, 400, 200);

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

        particles.createEmitter({
            frame: [ 'red', 'green', 'blue' ],
            x: 400,
            y: 100,
            speed: 300,
            gravityY: 400,
            lifespan: 4000,
            scale: 0.4,
            blendMode: 'ADD',
            deathZone: { type: 'onEnter', source: rect }
        });

        const graphics = this.add.graphics();

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

        graphics.strokeRectShape(rect);

    }
}

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

const game = new Phaser.Game(config);

Что такое deathZone?

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

Зона задаётся объектом с двумя полями: type и source. Поле source должно содержать экземпляр любого объекта, реализующего интерфейс Phaser Geometry (например, Rectangle, Circle, Triangle).

Разбор сцены и настройки

Весь код выполняется внутри сцены Example. В методе preload загружается атлас частиц 'flares'. Это текстура с набором разноцветных "вспышек".

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 rect = new Phaser.Geom.Rectangle(200, 350, 400, 200);

Здесь прямоугольник имеет координаты левого верхнего угла (200, 350), ширину 400 пикселей и высоту 200 пикселей.

Создание эмиттера со смертельной зоной

Далее создаётся менеджер частиц и эмиттер. Ключевой параметр — deathZone.

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

particles.createEmitter({
    frame: [ 'red', 'green', 'blue' ],
    x: 400,
    y: 100,
    speed: 300,
    gravityY: 400,
    lifespan: 4000,
    scale: 0.4,
    blendMode: 'ADD',
    deathZone: { type: 'onEnter', source: rect }
});

Эмиттер испускает частицы из точки (400, 100). Частицы летят вниз под действием гравитации (gravityY: 400). Их срок жизни по умолчанию — 4 секунды (lifespan: 4000). Однако, если частица на своём пути падает внутрь прямоугольника rect, она немедленно уничтожается, не дожидаясь конца своего lifespan. Параметр blendMode: 'ADD' задаёт аддитивное смешение цветов, что делает светящиеся частицы ярче при наложении.

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

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

const graphics = this.add.graphics();
graphics.lineStyle(1, 0x00ff00, 1);
graphics.strokeRectShape(rect);

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

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

Сцена включается в конфигурацию игры. Важный момент — для корректной работы частиц и их blend mode используется Phaser.WEBGL.

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

const game = new Phaser.Game(config);

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

Механизм deathZone типа 'onEnter' — это мощный и простой инструмент для контроля над жизненным циклом частиц. Вы можете использовать его не только с прямоугольниками, но и с кругами, эллипсами или произвольными многоугольниками. Для экспериментов попробуйте изменить тип зоны на 'onLeave' (частицы уничтожаются при выходе из области), создать несколько зон с разными геометриями или комбинировать смертельные зоны с другими силами эмиттера. Это откроет возможности для создания сложных и управляемых визуальных эффектов, таких как порталы, щиты или области ядовитого тумана.