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

При создании эффектов, таких как дождь, огонь или магические вспышки, часто нужно ограничить область их действия. Phaser 3 предоставляет мощный инструмент `bounds` для эмиттеров частиц, позволяющий задавать произвольные границы для их движения. В этой статье разберем, как создать систему частиц, которая будет отскакивать от заданных границ, а также визуализировать эти границы с помощью графики.

Версия 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 rect = new Phaser.Geom.Rectangle(100, 100, 600, 400);

        this.add.particles(400, 250, 'flares', {
            frame: [ 'red', 'yellow', 'green' ],
            lifespan: 4000,
            speed: { min: 150, max: 250 },
            scale: { start: 0.4, end: 0 },
            gravityY: 150,
            bounce: 0.8,
            bounds: rect,
            blendMode: 'ADD'
        });

        const graphics = this.add.graphics();

        graphics.lineStyle(1, 0x00ff00);
        graphics.strokeRectShape(rect);
    }
}

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

const game = new Phaser.Game(config);

Настройка сцены и загрузка атласа частиц

Для работы с частицами в Phaser 3 часто используется атлас — изображение, содержащее набор спрайтов (фреймов) для частиц. В методе preload мы загружаем такой атлас с помощью this.load.atlas(). Первый аргумент — ключ ресурса 'flares', по которому мы будем обращаться к атласу. Два следующих аргумента — пути к изображению и JSON-файлу с описанием фреймов.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.atlas('flares', 'assets/particles/flares.png', 'assets/particles/flares.json');

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

Основная логика размещается в методе create. Сначала мы определяем прямоугольную область с помощью Phaser.Geom.Rectangle. Она задается координатами левого верхнего угла (x, y), шириной и высотой.

const rect = new Phaser.Geom.Rectangle(100, 100, 600, 400);

Затем создается эмиттер частиц с помощью this.add.particles(). Первые два аргумента — это стартовая позиция эмиттера. Третий аргумент — ключ загруженного атласа. Четвертый аргумент — конфигурационный объект, который определяет поведение частиц. Ключевой параметр здесь — bounds. Мы передаем ему созданный прямоугольник rect. Это означает, что все частицы будут существовать и двигаться только в пределах этой области. При столкновении с границей они будут отскакивать, так как параметр bounce установлен в 0.8 (коэффициент упругости).

this.add.particles(400, 250, 'flares', {
    frame: [ 'red', 'yellow', 'green' ],
    lifespan: 4000,
    speed: { min: 150, max: 250 },
    scale: { start: 0.4, end: 0 },
    gravityY: 150,
    bounce: 0.8,
    bounds: rect,
    blendMode: 'ADD'
});

Визуализация границ с помощью Graphics

Чтобы визуально видеть, где находятся границы для частиц, мы рисуем прямоугольник поверх сцены. Для этого используется объект Graphics. Сначала мы создаем его с помощью this.add.graphics(). Затем задаем стиль линии: толщину `1и цвет0x00ff00(зеленый). После этого рисуем контур прямоугольника, используя ранее созданный объектrect`.

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

Этот прямоугольник не является физическим объектом и служит только для отладки. Частицы не взаимодействуют с ним — они взаимодействуют с невидимой областью, переданной в параметр bounds.

Разбор параметров конфигурации эмиттера

Давайте подробнее рассмотрим свойства, переданные в конфигурационный объект эмиттера:

- frame: Массив имен фреймов из атласа. Частицы будут случайным образом выбирать один из этих цветов. - lifespan: Время жизни частицы в миллисекундах. - speed: Диапазон начальной скорости частицы. Задается объектом с min и max. - scale: Объект, определяющий начальный и конечный масштаб частицы. Здесь частицы плавно исчезают, уменьшаясь от 0.4 до `0`. - gravityY: Сила гравитации, приложенная по оси Y. Положительное значение тянет частицы вниз. - bounce: Коэффициент отскока при столкновении с границами. Значение 0.8 означает, что частица сохранит 80% своей скорости. - blendMode: Режим наложения цвета. 'ADD' создает эффект свечения, складывая цвета частиц и фона.

{
    frame: [ 'red', 'yellow', 'green' ],
    lifespan: 4000,
    speed: { min: 150, max: 250 },
    scale: { start: 0.4, end: 0 },
    gravityY: 150,
    bounce: 0.8,
    bounds: rect,
    blendMode: 'ADD'
}

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

Использование параметра bounds — это простой и эффективный способ контролировать движение системы частиц в Phaser 3. Вы можете создавать не только прямоугольные, но и любые другие области, используя геометрию Phaser. Для экспериментов попробуйте изменить форму границ на круг (Phaser.Geom.Circle), динамически перемещать границы во время игры или комбинировать несколько эмиттеров с разными областями для создания сложных эффектов, таких как водопад, ограниченный ущельем.