О чем этот пример
Создание визуальных эффектов — ключевая часть игровой разработки. Частицы оживляют сцену, но иногда их поведение нужно строго контролировать. В этом примере мы разберем, как создать зону смерти (death zone) для эмиттера частиц в Phaser 3, которая будет следовать за курсором мыши, мгновенно уничтожая любые частицы, попадающие в нее. Этот прием полезен для симуляции поглотителей энергии, опасных областей или создания интерактивных демонстраций физики частиц.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.55.2.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
zone;
graphics;
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 emitZone = new Phaser.Geom.Rectangle(0, 0, 800, 600);
// Any particles that enter this shape will be killed instantly
this.deathZone = new Phaser.Geom.Circle(0, 0, 48);
const particles = this.add.particles('flares');
const emitter = particles.createEmitter({
frame: [ 'red', 'green', 'blue' ],
speed: { min: -20, max: 20 },
lifespan: 10000,
quantity: 2,
scale: { min: 0.1, max: 0.4 },
alpha: { start: 1, end: 0 },
blendMode: 'ADD',
emitZone: { source: emitZone },
deathZone: { type: 'onEnter', source: this.deathZone }
});
const zone = emitter.deathZones[0].source;
this.graphics = this.add.graphics();
this.input.on('pointermove', pointer =>
{
zone.x = pointer.worldX;
zone.y = pointer.worldY;
});
this.zone = zone;
}
update ()
{
this.graphics.clear();
this.graphics.lineStyle(1, 0x00ff00, 1);
this.graphics.strokeCircleShape(this.zone);
}
}
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое зона смерти (Death Zone)?
В Phaser эмиттер частиц может работать с двумя типами зон: зоной излучения (emitZone) и зоной смерти (deathZone). Зона смерти — это геометрическая область, которая уничтожает частицы при определенном условии.
Условие задается параметром type. В нашем примере используется тип 'onEnter', что означает мгновенное уничтожение частицы в момент пересечения границы зоны. Это отличный инструмент для создания четких границ или динамических препятствий для частиц.
Настройка эмиттера и зон
Код настройки происходит в методе create(). Сначала мы определяем две геометрические фигуры: прямоугольник для излучения и круг для уничтожения. Ключевая конфигурация эмиттера передается в метод createEmitter().
const emitZone = new Phaser.Geom.Rectangle(0, 0, 800, 600);
this.deathZone = new Phaser.Geom.Circle(0, 0, 48);
const emitter = particles.createEmitter({
frame: [ 'red', 'green', 'blue' ],
speed: { min: -20, max: 20 },
lifespan: 10000,
quantity: 2,
scale: { min: 0.1, max: 0.4 },
alpha: { start: 1, end: 0 },
blendMode: 'ADD',
emitZone: { source: emitZone },
deathZone: { type: 'onEnter', source: this.deathZone }
});
Обратите внимание на параметры emitZone и deathZone. Они принимают объект с полями source (источник — геометрическая фигура) и type (только для deathZone). Частицы будут рождаться в случайных точках внутри прямоугольника emitZone и умирать при входе в круг deathZone.
Привязка зоны смерти к курсору
Чтобы зона смерти следовала за указателем мыши, нам нужно получить ссылку на исходный объект геометрии и обновлять его координаты в обработчике события pointermove.
const zone = emitter.deathZones[0].source;
this.input.on('pointermove', pointer =>
{
zone.x = pointer.worldX;
zone.y = pointer.worldY;
});
this.zone = zone;
Массив emitter.deathZones содержит все активные зоны смерти эмиттера. Мы берем первую (и в данном случае единственную) и сохраняем ссылку на ее source — наш круг (Phaser.Geom.Circle). В событии pointermove мы перезаписываем координаты центра круга (`x,y) на мировые координаты курсора (pointer.worldX,pointer.worldY`).
Визуализация зоны для отладки
Чтобы видеть, где находится наша невидимая зона смерти, мы рисуем ее контур с помощью графического объекта (Graphics). Это делается в методе update(), который вызывается каждый кадр.
update ()
{
this.graphics.clear();
this.graphics.lineStyle(1, 0x00ff00, 1);
this.graphics.strokeCircleShape(this.zone);
}
Сначала мы очищаем графику от предыдущего кадра с помощью clear(). Затем задаем стиль линии: толщина 1, цвет зеленый (0x00ff00), непрозрачность 1. И, наконец, рисуем обводку (strokeCircleShape) нашей круглой зоны. Без этой визуализации отслеживать положение зоны было бы невозможно.
Что попробовать дальше
Мы создали интерактивную систему, где смертоносная зона, привязанная к курсору, контролирует жизнь частиц. Это демонстрирует мощь и гибкость системы частиц Phaser 3. Для экспериментов попробуйте изменить геометрию зоны смерти на Rectangle или Triangle, увеличьте ее размер, измените тип deathZone.type на 'onLeave' (уничтожение при выходе) или добавьте несколько зон с разным поведением. Это открывает путь к созданию сложных и управляемых игровых эффектов.
