О чем этот пример
Фильтры в Phaser 3 — мощный инструмент для постобработки графики, но что если вам нужно проанализировать результат их работы? Пример `sampler.js` демонстрирует редкую возможность: взятие пробы цвета (`sampler`) с изображения, к которому уже применены другие фильтры. Это открывает двери для создания динамических визуальных связей, например, когда цвет фона сцены синхронизируется с цветом определенной точки на обработанном спрайте, независимо от действующих на нем эффектов пикселизации и размытия.
Версия 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('card2', 'assets/pics/card2.png');
}
create ()
{
const card = this.add.image(640, 360, 'card2');
// Add filters to the card.
card.enableFilters();
// Pixelate the card.
const pixelate = card.filters.internal.addPixelate(30);
// Sample the card at the center and update the background color.
card.filters.internal.addSampler((color) => {
this.game.renderer.config.backgroundColor = color;
}, { x: 142, y: 200 });
// Blur the card. The sampler is unaffected.
const blur = card.filters.internal.addBlur(0, 2, 2, 2);
blur.setPaddingOverride(null);
this.tweens.add({
targets: pixelate,
amount: -1,
duration: 10000,
yoyo: true,
loop: -1
});
this.tweens.add({
targets: blur,
strength: 0,
duration: 10000,
yoyo: true,
loop: -1
});
}
}
const config = {
type: Phaser.AUTO,
width: 1280,
height: 720,
backgroundColor: '#000000',
parent: 'phaser-example',
scene: Example
};
let game = new Phaser.Game(config);
Подготовка сцены и загрузка ресурсов
Как и в любой сцене Phaser, работа начинается с методов жизненного цикла. В preload() мы загружаем единственное изображение — карту. Обратите внимание на использование setBaseURL, которое позволяет задать базовый путь для всех последующих загрузок, что удобно для работы с внешними ресурсами.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('card2', 'assets/pics/card2.png');
}
В create() мы создаем основной спрайт — карту — и сразу разрешаем применение к нему фильтров с помощью метода enableFilters(). Без этого вызова система фильтров для этого спрайта будет неактивна.
const card = this.add.image(640, 360, 'card2');
card.enableFilters();
Добавление фильтров: порядок имеет значение
Фильтры применяются к спрайту в том порядке, в котором они добавлены. Внутренний менеджер фильтров доступен через card.filters.internal. Первым делом добавляется пикселизация с высоким значением amount (30), что сильно увеличит размер видимых пикселей.
const pixelate = card.filters.internal.addPixelate(30);
Следующим идет ключевой элемент примера — Sampler. Это особый фильтр, который не изменяет изображение, а берет пробу цвета в указанной точке (относительно спрайта с уже примененными до него фильтрами) и передает этот цвет в callback-функцию. Точка { x: 142, y: 200 } — это координата внутри спрайта карты.
card.filters.internal.addSampler((color) => {
this.game.renderer.config.backgroundColor = color;
}, { x: 142, y: 200 });
Затем добавляется фильтр размытия. Важный нюанс: чтобы размытие не "вылезало" за границы спрайта и не влияло на пробу, его padding отменяется через setPaddingOverride(null). Фильтр Sampler, добавленный до размытия, будет брать цвет с уже пикселизированного, но еще не размытого изображения.
const blur = card.filters.internal.addBlur(0, 2, 2, 2);
blur.setPaddingOverride(null);
Анимация параметров фильтров
Для наглядности параметры добавленных фильтров анимируются с помощью системы твинов Phaser. Твин для пикселизации плавно меняет amount от 30 до -1 и обратно, создавая эффект "дыхания" пикселей. Значение -1 практически отключает фильтр.
this.tweens.add({
targets: pixelate,
amount: -1,
duration: 10000,
yoyo: true,
loop: -1
});
Аналогичный твин применяется к силе размытия (strength), меняя ее от 2 до 0. Это создает циклическое появление и исчезновение эффекта размытия. Обратите внимание, что анимация strength не влияет на работу Sampler — он продолжает сэмплировать цвет на этапе, предшествующем размытию.
this.tweens.add({
targets: blur,
strength: 0,
duration: 10000,
yoyo: true,
loop: -1
});
Конфигурация игры и запуск
Код завершается стандартной конфигурацией игры. Ключевой момент — изначальный цвет фона задан черным (#000000), но он будет мгновенно переопределен в callback Sampler'а при создании сцены.
const config = {
type: Phaser.AUTO,
width: 1280,
height: 720,
backgroundColor: '#000000',
parent: 'phaser-example',
scene: Example
};
let game = new Phaser.Game(config);
Что попробовать дальше
Пример наглядно показывает, как Sampler работает в конвейере фильтров: он сэмплирует цвет на том этапе обработки, на котором был добавлен, игнорируя последующие эффекты. Это мощный инструмент для создания обратной связи между визуальными элементами. Для экспериментов попробуйте
- Изменить координаты сэмплирования в реальном времени, следя за курсором мыши
- Использовать полученный цвет не для фона, а для окрашивания других спрайтов или частиц
- Добавить несколько
Sampler'ов в разные точки изображения и смешивать полученные цвета
