О чем этот пример
В Phaser контейнеры (`Container`) — это мощный инструмент для группировки игровых объектов, но иногда их поведение может мешать. Например, вы хотите временно скрыть целую группу элементов (меню, набор врагов, UI-слой) от рендеринга и интерактивности. Метод `camera.ignore()` позволяет исключить объекты из области видимости конкретной камеры, не удаляя их из сцены. Эта статья покажет, как использовать `ignore()` для контейнеров на практике. Вы научитесь точечно управлять видимостью сложных групп объектов, что полезно для реализации пауз, скрытых зон, временных эффектов и оптимизации рендеринга.
Версия 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.image('logo', 'assets/sprites/phaser3-logo.png');
}
create ()
{
const container1 = this.add.container(400, 100);
const container2 = this.add.container(400, 300);
const container3 = this.add.container(400, 500);
const image1 = this.add.image(0, 0, 'logo').setInteractive();
const image2 = this.add.image(0, 0, 'logo').setInteractive();
const image3 = this.add.image(0, 0, 'logo').setInteractive();
container1.add(image1);
container2.add(image2);
container3.add(image3);
const text = this.add.text(10, 10, '', { font: '16px Courier', fill: '#00ff00' });
image1.on('pointerover', () =>
{
text.setText('Over Image 1');
});
image2.on('pointerover', () =>
{
text.setText('Over Image 2');
});
image3.on('pointerover', () =>
{
text.setText('Over Image 3');
});
// Ignore container2
this.cameras.main.ignore(container2);
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Основная логика примера
В примере создается сцена с тремя контейнерами, каждый из которых содержит интерактивное изображение логотипа Phaser. При наведении курсора на любое изображение в верхнем левом углу появляется текст, указывающий, на какой именно объект наведен курсор.
Ключевой момент — вызов this.cameras.main.ignore(container2);. Эта инструкция заставляет главную камеру игнорировать весь контейнер container2 и все его дочерние элементы. Давайте разберем код по шагам.
Создание контейнеров и добавление изображений
Сначала создаются три контейнера на разных вертикальных позициях (Y = 100, 300, 500). Внутри каждого контейнера создается и добавляется изображение с логотипом. Важно отметить, что координаты изображений задаются относительно их родительского контейнера (0, 0).
const container1 = this.add.container(400, 100);
const container2 = this.add.container(400, 300);
const container3 = this.add.container(400, 500);
const image1 = this.add.image(0, 0, 'logo').setInteractive();
const image2 = this.add.image(0, 0, 'logo').setInteractive();
const image3 = this.add.image(0, 0, 'logo').setInteractive();
container1.add(image1);
container2.add(image2);
container3.add(image3);
Метод .setInteractive() делает каждое изображение чувствительным к событиям ввода, таким как pointerover (наведение курсора).
Обработка событий и вывод информации
Для каждого изображения назначается обработчик события pointerover. При наведении курсора текст в левом верхнем углу сцены обновляется, показывая номер активного изображения. Это помогает визуально подтвердить интерактивность объектов.
const text = this.add.text(10, 10, '', { font: '16px Courier', fill: '#00ff00' });
image1.on('pointerover', () => {
text.setText('Over Image 1');
});
// ... Аналогично для image2 и image3
Включение игнорирования для контейнера
Самая важная строка в этом примере — вызов метода ignore() у главной камеры. В качестве аргумента передается ссылка на контейнер, который нужно скрыть.
this.cameras.main.ignore(container2);
После этого вызова контейнер container2 и все его дочерние элементы (в данном случае image2) перестают отображаться на экране. Более того, они также перестают быть интерактивными — событие pointerover для image2 больше не срабатывает, даже если курсор находится в той области экрана, где должен быть контейнер. Это происходит потому, что камера полностью исключает этот объект из своего конвейера рендеринга и обработки ввода.
Практическое применение и нюансы
Метод ignore() — это не то же самое, что установка setVisible(false) для объекта. Объект остается частью сцены, обновляется (update), но просто не рисуется конкретной камерой. Это позволяет:
* **Эффективно скрывать группы объектов:** Игнорирование контейнера мгновенно скрывает все его содержимое.
* **Создавать слои видимости:** Можно иметь несколько камер и настраивать, какие объекты видит каждая из них.
* **Оптимизировать производительность:** Временное игнорирование тяжелых групп объектов может повысить FPS.
Важный нюанс: чтобы вернуть объект в область видимости камеры, используется метод camera.ignore() с тем же объектом, но вторым аргументом false, или метод camera.resetIgnore().
// Прекратить игнорировать container2
this.cameras.main.ignore(container2, false);
// ИЛИ сбросить все игнорирования для камеры
// this.cameras.main.resetIgnore();
Что попробовать дальше
Метод camera.ignore() — это точный инструмент для управления видимостью объектов через камеру в Phaser. Он особенно эффективен для работы с контейнерами, позволяя массово скрывать или показывать сложные группы игровых сущностей.
**Идеи для экспериментов:**
1. Создайте вторую камеру (this.cameras.add) и настройте разный набор игнорируемых контейнеров для главной и дополнительной камер. Это основа для picture-in-picture или сложных UI.
2. Динамически включайте и выключайте игнорирование контейнера по таймеру или событию (например, нажатию клавиши), создавая эффект мигания для группы объектов.
3. Проверьте, как игнорирование контейнера влияет на дочерние объекты с собственными физическими телами (physics.add.sprite). Останется ли тело активным в физическом мире?
