Маски из Graphics-объектов

Phaser предоставляет гибкий механизм работы с масками, позволяющий скрывать или показывать части объектов сцены на основе формы, заданной другим объектом. Одним из наиболее удобных способов создания масок является использование Graphics-объектов, которые позволяют рисовать произвольные фигуры с последующим применением их как маски к спрайтам, контейнерам или другим графическим элементам.

Создание Graphics-объекта

Graphics — это объект для рисования в Phaser, который поддерживает линии, прямоугольники, круги, многоугольники и сложные комбинации. Создание объекта осуществляется через сцену:

const maskGraphics = this.add.graphics();

После создания можно задавать цвет, прозрачность и рисовать фигуры:

maskGraphics.fillStyle(0xffffff, 1); // белый цвет, полностью непрозрачный
maskGraphics.fillRect(100, 50, 200, 150); // прямоугольник (x, y, width, height)

Применение Graphics как маски

Чтобы Graphics-объект использовался как маска, его нужно преобразовать в BitmapMask или GeometryMask. GeometryMask чаще используется с Graphics-объектами, так как он поддерживает динамическое изменение формы:

const mask = maskGraphics.createGeometryMask();
sprite.setMask(mask);
  • sprite — объект, к которому применяется маска.
  • Маска скрывает все части объекта, находящиеся за пределами нарисованной фигуры.

Динамические маски

Graphics-объект можно изменять в любой момент, и маска будет автоматически обновляться. Это позволяет создавать анимации, эффекты «стерки» или прогресс-бары:

maskGraphics.clear();
maskGraphics.fillStyle(0xffffff, 1);
maskGraphics.fillCircle(150, 150, radius); // radius может изменяться в update()

Такой подход дает возможность плавно изменять форму маски в реальном времени.

Комбинирование нескольких фигур

Graphics поддерживает рисование нескольких фигур в одном объекте. Все нарисованные области объединяются и формируют единую маску. Пример маски, состоящей из прямоугольника и круга:

maskGraphics.fillStyle(0xffffff, 1);
maskGraphics.fillRect(50, 50, 100, 100);
maskGraphics.fillCircle(200, 200, 50);

const mask = maskGraphics.createGeometryMask();
sprite.setMask(mask);

Маски для контейнеров

Маска может применяться не только к отдельным спрайтам, но и к контейнерам:

const container = this.add.container(0, 0);
container.add([sprite1, sprite2]);

container.setMask(mask);

В этом случае все дочерние объекты контейнера будут отображаться только в пределах маски.

Управление видимостью и прозрачностью

Для удобного управления маской можно использовать свойства alpha и visible Graphics-объекта. При установке alpha = 0 фигура становится невидимой, но маска продолжает работать:

maskGraphics.alpha = 0; // маска работает, фигура не видна

Это позволяет создавать чистые эффекты без визуального отображения самой маски.

Маски и производительность

  • Graphics-объекты в качестве масок могут быть динамическими, но сложные формы с большим количеством вершин могут снижать производительность.
  • Для статических масок рекомендуется создавать их один раз и использовать повторно.
  • GeometryMask использует шейдеры WebGL, поэтому обновления формы менее затратны, чем использование BitmapMask с растровыми изображениями.

Практические примеры

  1. Прогресс-бар загрузки:
const progressBar = this.add.sprite(100, 100, 'bar');
const maskGraphics = this.add.graphics();
maskGraphics.fillStyle(0xffffff, 1);
maskGraphics.fillRect(0, 0, 0, 20); // изначально нулевая ширина

const mask = maskGraphics.createGeometryMask();
progressBar.setMask(mask);

// В update()
maskGraphics.clear();
maskGraphics.fillStyle(0xffffff, 1);
maskGraphics.fillRect(0, 0, progressWidth, 20);
  1. Скрытие объекта по кругу:
const maskGraphics = this.add.graphics();
maskGraphics.fillStyle(0xffffff, 1);
maskGraphics.fillCircle(player.x, player.y, 50);

sprite.setMask(mask);

// В update() маска следует за игроком
maskGraphics.clear();
maskGraphics.fillStyle(0xffffff, 1);
maskGraphics.fillCircle(player.x, player.y, 50);

Использование Graphics-объектов как масок открывает широкие возможности для динамических эффектов и позволяет создавать интерактивные сцены с плавными переходами и сложными формами. Гибкость GeometryMask делает его основным инструментом для визуальных экспериментов в Phaser.