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

Управление тысячами частиц — ключевой навык в создании визуальных эффектов для игр. В этой статье мы разберем, как использовать `deathZone` в эмиттере частиц 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 ()
    {
        //  Any particles that leave this shape will be killed instantly
        const circle = new Phaser.Geom.Circle(400, 300, 200);

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

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

        const graphics = this.add.graphics();

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

        graphics.strokeCircleShape(circle);
    }
}

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

const game = new Phaser.Game(config);

Подготовка сцены и загрузка атласа

Все начинается с загрузки необходимых ресурсов. В нашем случае это атлас частиц 'flares', который содержит несколько текстур для эффектов.

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 вызывается автоматически для загрузки ресурсов. setBaseURL задает базовый путь, что позволяет указывать только относительные пути для load.atlas. Атлас 'flares' — это изображение с несколькими текстурами (фреймами) и JSON-файл, описывающий их расположение.

Создание геометрической зоны смерти

Смертельная зона определяется с помощью геометрического объекта Phaser. Мы создаем круг, который будет служить границей.

const circle = new Phaser.Geom.Circle(400, 300, 200);

Класс Phaser.Geom.Circle создает круг с центром в точке (400, 300) и радиусом 200 пикселей. Любая частица, которая покинет эту область, будет немедленно уничтожена. Позже мы визуализируем эту зону с помощью Graphics.

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

Следующий шаг — создание системы частиц (менеджера) и настройка эмиттера с параметрами и зоной смерти.

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

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

this.add.particles('flares') создает менеджер частиц, который использует загруженный атлас. Метод createEmitter настраивает эмиттер: * frame: Массив имен фреймов из атласа для частиц. * `x,y`: Точка испускания частиц (центр круга). * speed: Начальная скорость движения. * lifespan: Время жизни частицы в миллисекундах, если ее не уничтожит зона смерти. * scale: Масштаб частиц. * blendMode: Режим наложения 'ADD' для ярких, светящихся эффектов. * deathZone: Ключевой параметр. Объект с type: 'onLeave' указывает, что частицы уничтожаются при выходе из source (источника) — нашего круга.

Визуализация границы зоны

Чтобы видеть границу смертельной зоны во время разработки и отладки, мы рисуем круг с помощью Graphics.

const graphics = this.add.graphics();
graphics.lineStyle(1, 0x00ff00, 1);
graphics.strokeCircleShape(circle);

this.add.graphics() создает объект для программного рисования. lineStyle задает стиль линии: толщина 1, цвет зеленый (0x00ff00), альфа-канал 1 (непрозрачный). strokeCircleShape рисует контур ранее созданного круга circle. Это чисто визуальный вспомогательный элемент.

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

Весь пример оборачивается в стандартную конфигурацию игры Phaser.

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

const game = new Phaser.Game(config);

В объекте config: * type: Phaser.WEBGL использует WebGL рендерер для лучшей производительности частиц. * width, height — размеры canvas. * backgroundColor — черный фон для контраста. * parent — ID HTML-элемента, в который будет встроен canvas. * scene — ссылка на наш класс сцены Example. Создание экземпляра Phaser.Game с этой конфигурацией запускает игру.

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

Использование deathZone типа 'onLeave' — это мощный и эффективный способ контролировать область действия частиц, освобождая ресурсы и создавая четкие визуальные границы эффектов. Для экспериментов попробуйте: 1. Заменить Phaser.Geom.Circle на Phaser.Geom.Rectangle или Phaser.Geom.Ellipse. 2. Использовать type: 'onEnter', чтобы уничтожать частицы при *входе* в зону. 3. Динамически изменять размер или положение источника зоны (source) во время выполнения для создания "движущихся" полей.