О чем этот пример
Порядок отрисовки спрайтов и частиц в 2D-играх критически важен для визуальной целостности сцены. Частицы от взрыва должны быть поверх снаряда, но под интерфейсом. Встроенная в Phaser система глубины (depth) решает эту задачу глобально, но что, если нужно быстро изменить порядок отрисовки только для частиц конкретного эмиттера? На помощь приходит свойство `particleBringToTop`. Эта статья на практическом примере покажет, как динамически менять слой отрисовки частиц относительно других игровых объектов.
Версия 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('blocks', 'assets/sprites/blocks.png', 'assets/sprites/blocks.json');
}
create ()
{
const emitter = this.add.particles(100, 300);
emitter.setConfig({
texture: 'blocks',
frame: 'redmonster',
lifespan: 5000,
angle: { min: -30, max: 30 },
speed: 150,
frequency: 200
});
const text = this.add.text(10, 10, 'Click to change. bringToTop: true');
this.input.on('pointerdown', () => {
if (emitter.particleBringToTop)
{
emitter.particleBringToTop = false;
}
else
{
emitter.particleBringToTop = true;
}
text.setText(`Click to change. bringToTop: ${emitter.particleBringToTop}`);
});
window.emma = emitter;
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Создание эмиттера частиц с текстурой из атласа
В методе preload загружается атлас текстур blocks, который содержит несколько спрайтов в одном изображении. Это эффективный способ работы с графикой.
this.load.atlas('blocks', 'assets/sprites/blocks.png', 'assets/sprites/blocks.json');
В create создается эмиттер частиц в точке (100, 300). Конфигурация задается методом setConfig. Ключевые параметры:
* texture и frame: определяют, какое изображение из атласа будет использоваться для каждой частицы (в данном случае кадр с именем 'redmonster').
* lifespan: время жизни частицы в миллисекундах.
* angle и speed: определяют направление и скорость разлета.
* frequency: интервал между испусканием частиц.
const emitter = this.add.particles(100, 300);
emitter.setConfig({
texture: 'blocks',
frame: 'redmonster',
lifespan: 5000,
angle: { min: -30, max: 30 },
speed: 150,
frequency: 200
});
Свойство particleBringToTop и его роль
Эмиттер частиц в Phaser — это контейнер (ParticleEmitter), который управляет множеством отдельных частиц, являющихся игровыми объектами (Particle). По умолчанию частицы отрисовываются в том порядке, в котором они были добавлены в сцену относительно других объектов.
Свойство particleBringToTop — это флаг, принадлежащий самому эмиттеру. Когда он установлен в true, **все частицы, испускаемые этим эмиттером, будут принудительно отрисовываться поверх всех других игровых объектов в этой сцене**. Это локальная и быстрая альтернатива ручной настройке свойства depth для каждого эмиттера или объектов вокруг него.
Важно: это свойство влияет на все частицы эмиттера, включая уже выпущенные. Его переключение немедленно изменит порядок отрисовки.
Динамическое переключение порядка отрисовки
В примере добавлен текст для отображения текущего состояния и обработчик клика мыши. По каждому клику значение particleBringToTop инвертируется, что мгновенно меняет слой, на котором рисуются частицы.
const text = this.add.text(10, 10, 'Click to change. bringToTop: true');
this.input.on('pointerdown', () => {
if (emitter.particleBringToTop)
{
emitter.particleBringToTop = false;
}
else
{
emitter.particleBringToTop = true;
}
text.setText(`Click to change. bringToTop: ${emitter.particleBringToTop}`);
});
Попробуйте запустить пример и добавить другие спрайты на сцену (например, через this.add.image). Вы увидите, как клик заставляет частицы перескакивать то под, то над этими спрайтами.
Когда использовать bringToTop, а когда систему depth
particleBringToTop — это инструмент для быстрого прототипирования и решения простых задач.
* **Используйте его**, когда нужно гарантировать, что частицы эффекта (огонь, дым, магическая аура) всегда будут поверх определенного персонажа или объекта без сложной логики.
* **Не используйте его**, если в сцене есть сложная многослойная графика (задний план, средний план, несколько слоев интерфейса). В этом случае надежнее использовать встроенную систему глубины Phaser, назначая объектам и эмиттерам числовые значения depth. Объекты с большим значением depth отрисовываются поверх объектов с меньшим значением.
// Альтернатива: явное управление глубиной
emitter.setDepth(10);
someBackgroundImage.setDepth(1);
playerSprite.setDepth(5);
particleBringToTop по сути временно присваивает частицам очень большое значение глубины.
Что попробовать дальше
Свойство particleBringToTop — это удобный переключатель для управления визуальным приоритетом частиц в реальном времени. Оно идеально подходит для отладки, прототипирования визуальных эффектов и реализации механик, где порядок отрисовки должен меняться по игровым событиям (например, частицы щита поверх врага).
**Идеи для экспериментов:**
1. Создайте два эмиттера с разными текстурами и переключайте bringToTop только у одного. Наблюдайте за их взаимодействием.
2. Добавьте анимацию спрайту и попробуйте «спрятать» его за частицами дыма, отключив флаг.
3. Свяжите переключение флага не с кликом, а с игровым событием, например, с получением урона игроком (частицы крови поверх всего).
