О чем этот пример
При разработке игр часто возникает необходимость управлять группами игровых объектов одновременно: скрывать, перемещать или применять эффекты. Ручное перебор всех спрайтов неэффективно и усложняет код. Пример демонстрирует использование `Layer` — мощного контейнера Phaser, который позволяет работать с группой объектов, включая вложенные слои, как с единой сущностью. Это упрощает организацию сцены, управление видимостью и повышает читаемость кода.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('elephant', 'assets/sprites/elephant.png');
this.load.image('coke', 'assets/sprites/cokecan.png');
}
create ()
{
const elephantLayer = this.add.layer();
const cokeLayer = this.add.layer();
for (let i = 0; i < 32; i++)
{
let x = Phaser.Math.Between(50, 750);
let y = Phaser.Math.Between(100, 550);
elephantLayer.add(this.make.sprite({ x, y, key: 'elephant' }));
}
for (let i = 0; i < 32; i++)
{
let x = Phaser.Math.Between(50, 750);
let y = Phaser.Math.Between(100, 550);
cokeLayer.add(this.make.sprite({ x, y, key: 'coke' }));
}
elephantLayer.add(cokeLayer);
const button1 = this.add.text(10, 10, 'Hide Child Layer', { backgroundColor: '#0000aa', fixedWidth: 210, align: 'center' });
const button2 = this.add.text(10, 48, 'Hide Parent Layer', { backgroundColor: '#0000aa', fixedWidth: 210, align: 'center' });
button1.setPadding(0, 8, 0, 8);
button2.setPadding(0, 8, 0, 8);
button1.setInteractive();
button2.setInteractive();
button1.on('pointerdown', () => {
cokeLayer.visible = !cokeLayer.visible;
});
button2.on('pointerdown', () => {
elephantLayer.visible = !elephantLayer.visible;
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое Layer и зачем он нужен
Layer — это специальный игровой объект-контейнер, который может содержать в себе другие объекты: спрайты, текст, частицы или даже другие слои. Ключевая особенность в том, что действия, примененные к слою (например, изменение свойства visible), автоматически влияют на все его дочерние элементы.
const elephantLayer = this.add.layer();
const cokeLayer = this.add.layer();
В этом примере создаются два независимых слоя. Они пока пусты, но уже готовы к добавлению объектов. Слои сами по себе не отображаются, они служат логическими группами.
Наполнение слоев объектами
Объекты добавляются в слой с помощью метода add(). В примере используется фабрика this.make.sprite() для создания спрайтов со случайными координатами. Это удобный способ быстрого прототипирования.
for (let i = 0; i < 32; i++) {
let x = Phaser.Math.Between(50, 750);
let y = Phaser.Math.Between(100, 550);
elephantLayer.add(this.make.sprite({ x, y, key: 'elephant' }));
}
Важно: объект, добавленный в слой, автоматически становится его дочерним элементом в дереве отображения. Самый мощный трюк — это возможность делать слои вложенными, создавая иерархии.
elephantLayer.add(cokeLayer);
Теперь cokeLayer становится дочерним для elephantLayer. Все кансы кока-колы логически находятся «внутри» слоя со слонами.
Управление видимостью через иерархию
Свойство visible у слоя работает рекурсивно. Если скрыть родительский слой, скроются и все его дети, независимо от их собственного значения visible.
В примере создаются две текстовые кнопки, которые меняют видимость слоев.
button1.on('pointerdown', () => {
cokeLayer.visible = !cokeLayer.visible;
});
button2.on('pointerdown', () => {
elephantLayer.visible = !elephantLayer.visible;
});
Нажмите «Hide Child Layer» — скроются только спрайты из cokeLayer. Нажмите «Hide Parent Layer» — скроется весь elephantLayer, а вместе с ним и вложенный cokeLayer, даже если до этого он был видим. Это наглядно демонстрирует принцип иерархического управления.
Практические сценарии использования
Слои — это не просто про видимость. Их можно использовать для: * **Групповых трансформаций:** Смещение, вращение или масштабирование всего слоя. * **Логического разделения:** Отдельный слой для фона, для игровых объектов (персонажи, враги) и для интерфейса (HUD). * **Быстрого включения/выключения целых механизмов:** Например, слой со всеми объектами меню-паузы. * **Управления глубиной (depth):** Назначение глубины всему слою сразу, а не каждому объекту по отдельности.
Использование слоев делает код сцены чище и модульнее, так как логически связанные объекты собраны вместе.
Что попробовать дальше
Layer в Phaser — это фундаментальный инструмент для структурирования игрового мира. Он позволяет управлять группами объектов иерархически, что критически важно для сложных сцен. Для экспериментов попробуйте: добавить слоям свойство alpha для одновременного затухания, перемещать весь слой с помощью setX/setY или создать глубокую вложенность из 3-4 слоев, чтобы увидеть, как свойства распространяются по цепочке.
