О чем этот пример
При создании сложных визуальных эффектов в Phaser разработчики часто используют контейнеры для группировки игровых объектов. Однако управление режимами наложения (blend modes) внутри контейнера имеет важную особенность: родительский контейнер может переопределять настройки своих детей. Эта статья объяснит, как правильно работать с режимами наложения в иерархии объектов, чтобы создавать именно те эффекты, которые вы задумали, без неожиданных визуальных артефактов.
Версия 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('grid', 'assets/pics/uv-grid-diag.png');
this.load.image('logo', 'assets/sprites/phaser3-logo.png');
}
create ()
{
this.add.image(400, 300, 'grid');
const image0 = this.add.image(0, -200, 'logo').setBlendMode(Phaser.BlendModes.ADD);
const image1 = this.add.image(0, 0, 'logo').setBlendMode(Phaser.BlendModes.DIFFERENCE);
const image2 = this.add.image(0, 200, 'logo').setBlendMode(Phaser.BlendModes.COLOR_DODGE);
const container = this.add.container(400, 300, [ image0, image1, image2 ]);
// If the Container has a blend mode set it will override the children
// Un-comment the following line and the child blend modes will be replaced by the Containers
// container.setBlendMode(Phaser.BlendModes.MULTIPLY);
}
}
const config = {
type: Phaser.CANVAS,
width: 800,
height: 600,
backgroundColor: '#010101',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое режимы наложения и зачем они нужны
Режимы наложения (blend modes) определяют, как пиксели одного графического объекта смешиваются с пикселями объектов под ним. Phaser предоставляет множество режимов: ADD для свечения, MULTIPLY для затемнения, SCREEN для осветления и другие. Это мощный инструмент для создания спецэффектов без дополнительных текстур.
В примере мы видим три спрайта логотипа Phaser, каждый со своим режимом наложения, размещенные на фоновой сетке. Каждый спрайт создается независимо со своим blend mode.
Создание объектов и установка режимов наложения
Давайте разберем код создания спрайтов. Каждый спрайт логотипа создается как отдельный игровой объект с помощью метода this.add.image(). Сразу после создания для каждого спрайта вызывается метод .setBlendMode() с разным параметром.
const image0 = this.add.image(0, -200, 'logo').setBlendMode(Phaser.BlendModes.ADD);
const image1 = this.add.image(0, 0, 'logo').setBlendMode(Phaser.BlendModes.DIFFERENCE);
const image2 = this.add.image(0, 200, 'logo').setBlendMode(Phaser.BlendModes.COLOR_DODGE);
Ключевой момент: координаты (0, -200), (0, 0) и (0, 200) задаются относительно будущего родителя — контейнера. Это локальные координаты внутри контейнера.
Группировка объектов в контейнере
После создания трех спрайтов они группируются в контейнер. Контейнер — это особый игровой объект, который служит родителем для других объектов. Все трансформации (позиция, поворот, масштаб), применяемые к контейнеру, автоматически применяются ко всем его детям.
const container = this.add.container(400, 300, [ image0, image1, image2 ]);
Здесь мы создаем контейнер в мировых координатах (400, 300) и передаем массив с тремя созданными спрайтами. Теперь все три спрайта позиционируются относительно центра контейнера.
Важное правило: приоритет режима наложения контейнера
В коде примера есть закомментированная строка, которая демонстрирует ключевую механику Phaser. Если контейнеру самому установить режим наложения, он переопределит режимы наложения всех своих дочерних объектов.
// container.setBlendMode(Phaser.BlendModes.MULTIPLY);
Если раскомментировать эту строку, все три спрайта (image0, image1, image2) перестанут использовать свои индивидуальные режимы ADD, DIFFERENCE и COLOR_DODGE. Вместо этого они все будут отрисовываться с режимом MULTIPLY контейнера. Это поведение по умолчанию в Phaser: blend mode родительского контейнера имеет приоритет.
Практические рекомендации по использованию
1. **Для независимых эффектов:** Если каждому дочернему объекту нужен свой уникальный blend mode, не устанавливайте blend mode для контейнера-родителя. 2. **Для единого эффекта:** Если вся группа объектов должна взаимодействовать с фоном одинаково (например, вся группа светится), установите blend mode на контейнер. Это эффективнее, чем устанавливать одинаковый режим каждому ребенку вручную. 3. **Порядок отрисовки:** Помните, что контейнер отрисовывает своих детей в том порядке, в котором они были добавлены в массив. Это влияет на итоговое наложение пикселей друг на друга внутри контейнера.
Что попробовать дальше
Понимание иерархии режимов наложения — ключ к контролируемому созданию визуальных эффектов в Phaser. Используйте blend mode контейнера для унификации эффекта группы объектов и индивидуальные blend mode детей для сложных композиций. Для экспериментов попробуйте: анимировать положение контейнера, чтобы вся группа двигалась как единое целое с эффектами; применить разные blend mode к контейнеру и посмотреть, как это повлияет на смешение группы с динамическим фоном.
