О чем этот пример
Визуальные эффекты играют ключевую роль в создании атмосферы игры. Фильтры в Phaser 3 предоставляют мощный инструмент для постобработки спрайтов прямо во время выполнения программы. В этой статье мы разберем, как добавить эффект виньетирования к изображению и управлять им по клику мыши. Этот подход полезен для динамического изменения настроения сцены, выделения ключевых объектов или создания эффектов старой фотографии и камеры без необходимости редактировать исходные текстуры.
Версия 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('pic', 'assets/pics/robot-ai.jpg');
}
create ()
{
const sprite = this.add.image(400, 300, 'pic');
const fx = sprite.enableFilters().filters.internal.addVignette();
this.add.text(10, 10, 'Click to toggle vignette on/off').setResolution(window.devicePixelRatio);
this.input.on('pointerdown', () => {
fx.active = !fx.active;
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#0a0067',
parent: 'phaser-example',
scene: Example
};
let game = new Phaser.Game(config);
Подготовка сцены и загрузка ассетов
Работа начинается с создания класса сцены, наследующего от Phaser.Scene. В методе preload мы устанавливаем базовый URL для загрузки ресурсов и загружаем одно изображение.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('pic', 'assets/pics/robot-ai.jpg');
}
Метод setBaseURL задает корневую папку для всех последующих загрузок в этой сцене. load.image регистрирует текстуру под ключом 'pic' для дальнейшего использования.
Создание спрайта и добавление фильтра
В методе create мы размещаем изображение в центре экрана и активируем для него систему фильтров.
const sprite = this.add.image(400, 300, 'pic');
const fx = sprite.enableFilters().filters.internal.addVignette();
Сначала создается спрайт с помощью this.add.image. Затем цепочка вызовов enableFilters() активирует фильтры для этого спрайта, а свойство filters.internal предоставляет доступ к внутреннему менеджеру фильтров. Метод addVignette() создает и добавляет экземпляр фильтра виньетирования, возвращая ссылку на него в переменную fx.
Интерактивное управление эффектом
Чтобы сделать эффект интерактивным, мы добавим текстовую подсказку и обработчик клика мыши.
this.add.text(10, 10, 'Click to toggle vignette on/off').setResolution(window.devicePixelRatio);
this.input.on('pointerdown', () => {
fx.active = !fx.active;
});
this.add.text создает текстовый объект в левом верхнем углу. Вызов setResolution обеспечивает четкое отображение текста на экранах с высоким pixel ratio.
Обработчик события pointerdown на глобальном объекте ввода this.input переключает булево свойство active у фильтра fx. Когда active равно false, фильтр перестает применяться к спрайту, и изображение возвращается к исходному виду.
Конфигурация и запуск игры
Запуск игры требует создания конфигурационного объекта и экземпляра Phaser.Game.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#0a0067',
parent: 'phaser-example',
scene: Example
};
let game = new Phaser.Game(config);
В конфиге задаются основные параметры: тип рендерера (Phaser.AUTO), размеры холста, цвет фона, ID HTML-элемента для вставки игры и класс основной сцены. Темно-синий фон (#0a0067) хорошо контрастирует с изображением, подчеркивая эффект виньетирования.
Что попробовать дальше
Всего несколько строк кода позволили добавить динамический визуальный эффект и управление им. Фильтры в Phaser 3 — это гибкий инструмент для постобработки. Для экспериментов попробуйте изменить параметры виньетирования (если API позволяет), комбинировать несколько фильтров на одном спрайте (например, addVignette и addGlow) или включать эффект не по клику, а по игровому событию, например, при получении урона персонажем.
