О чем этот пример
Маскирование — мощный инструмент для управления отображением объектов в Phaser 3. Обычная маска скрывает часть изображения, но что, если нужно показать только скрытую часть? В этом примере мы разберем, как использовать `BitmapMask` с инвертированием альфа-канала, чтобы создавать сложные визуальные эффекты, такие как проступающие сквозь облака лучи света или призрачные силуэты. Этот прием особенно полезен для создания атмосферных эффектов в играх, не прибегая к сложной работе с текстурами.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Scene extends Phaser.Scene
{
constructor()
{
super();
}
preload()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image("cloud", "assets/bugs/cloud.png");
this.load.image("mask", "assets/bugs/mask.png");
}
create()
{
this.cameras.main.setBackgroundColor(0xA9D4C9);
this.add.image(400, 280, "cloud");
const cloud2 = this.add.image(400, 300 + 100, "cloud");
const mask = this.make.image({
x: 400,
y: 500,
key: 'mask',
add: false
});
cloud2.mask = new Phaser.Display.Masks.BitmapMask(this, mask);
cloud2.mask.invertAlpha = true;
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Scene
}
new Phaser.Game(config);
Загрузка ресурсов и настройка сцены
В методе preload мы загружаем два изображения: основное изображение облака (cloud) и текстуру маски (mask). Базовый URL задается для удобства, чтобы не указывать полный путь к каждому ресурсу.
preload()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image("cloud", "assets/bugs/cloud.png");
this.load.image("mask", "assets/bugs/mask.png");
}
В create мы сначала задаем фоновый цвет сцены с помощью this.cameras.main.setBackgroundColor. Затем добавляем первое облако как обычное изображение. Оно будет служить фоном.
create()
{
this.cameras.main.setBackgroundColor(0xA9D4C9);
this.add.image(400, 280, "cloud");
Создание второго облака и маски
Второе облако (cloud2) мы размещаем ниже первого. Именно к нему будет применена маска.
const cloud2 = this.add.image(400, 300 + 100, "cloud");
Далее создается объект-изображение для самой маски. Ключевой параметр add: false указывает, что это изображение не нужно автоматически добавлять на дисплейный список сцены. Оно существует только как источник данных для маски.
const mask = this.make.image({
x: 400,
y: 500,
key: 'mask',
add: false
});
Применение BitmapMask с инвертированием
Здесь происходит самое важное. Мы создаем объект Phaser.Display.Masks.BitmapMask, передавая в конструктор текущую сцену (this) и изображение-источник (mask). Эта маска назначается второму облаку.
cloud2.mask = new Phaser.Display.Masks.BitmapMask(this, mask);
По умолчанию BitmapMask использует альфа-канал изображения-маски для определения прозрачных (скрытых) и непрозрачных (видимых) областей объекта. Установка свойства invertAlpha в true инвертирует это поведение: теперь видимыми становятся те части cloud2, которые соответствуют *прозрачным* пикселям в изображении mask, и наоборот.
cloud2.mask.invertAlpha = true;
Визуально это выглядит так, будто текстура маски 'вырезает' узор из второго облака, позволяя фону или другим объектам, находящимся под ним, проступить сквозь эти вырезы.
Конфигурация игры
Стандартная конфигурация игры Phaser 3. В поле scene передается ссылка на наш класс Scene.
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Scene
}
new Phaser.Game(config);
Что попробовать дальше
Инвертирование альфа-маски — простой, но эффективный способ создания сложных композиционных эффектов. С его помощью можно имитировать свет, проходящий сквозь листву или решетку, создавать эффекты растворения (dissolve) или причудливые UI-элементы. Для экспериментов попробуйте анимировать положение маски (mask.x, mask.y), менять ее размер или использовать в качестве маски не статичное изображение, а спрайт-лист для создания динамического эффекта 'проявления'.
