О чем этот пример
Визуальные эффекты — мощный инструмент для погружения игрока в атмосферу игры. Фильтр смещения (displacement) позволяет искажать текстуры, создавая эффекты волн, теплового марева, магических полей или деформации пространства. В этой статье мы разберем, как использовать этот фильтр в Phaser для создания анимированного искажения изображения с применением маски и твининга.
Версия 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('pic', 'assets/pics/skull-and-bones.jpg');
this.load.image('distort', 'assets/textures/distortion5.png');
}
create ()
{
const pic = this.add.image(400, 300, 'pic');
const fx = pic.enableFilters().filters.internal.addDisplacement('distort', -0.3, 0);
// Add a mask to the image.
const mask = this.add.circle(400, 300, 296, 0xffffff).setVisible(false);
mask.enableFilters().filters.external.addBlur();
pic.filters.external.addMask(mask);
this.tweens.add({
targets: fx,
x: 0.3,
yoyo: true,
loop: -1,
duration: 2000,
ease: 'sine.inout'
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка ресурсов
В методе preload загружаются два изображения: основное и текстура смещения. Текстура смещения — это черно-белое изображение (карта высот), где яркость пикселя определяет силу и направление смещения.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('pic', 'assets/pics/skull-and-bones.jpg');
this.load.image('distort', 'assets/textures/distortion5.png');
Создание и настройка фильтра смещения
В методе create сначала добавляется основное изображение. Затем для него активируется система фильтров. Фильтр смещения добавляется через filters.internal.addDisplacement. Первый аргумент — ключ текстуры смещения. Второй и третий аргументы (`x,y`) задают начальную силу смещения по осям. Значение -0.3 означает, что красный канал текстуры смещения изначально будет сдвигать пиксели изображения влево.
const pic = this.add.image(400, 300, 'pic');
const fx = pic.enableFilters().filters.internal.addDisplacement('distort', -0.3, 0);
Применение маски и внешнего фильтра
Чтобы эффект смещения не выходил за пределы круга, создается невидимая белая окружность, которая будет использоваться как маска. Для этой маски также активируются фильтры, и к ней добавляется внешний фильтр размытия (addBlur). Это смягчит края маски. Затем маска добавляется как внешний фильтр к основному изображению с помощью pic.filters.external.addMask(mask). Это ограничит область видимости изображения (и, следовательно, эффекта смещения) формой маски.
const mask = this.add.circle(400, 300, 296, 0xffffff).setVisible(false);
mask.enableFilters().filters.external.addBlur();
pic.filters.external.addMask(mask);
Анимация параметров фильтра
Чтобы эффект был динамичным, создается твин для объекта фильтра fx. Твин анимирует свойство `x(силу смещения по горизонтали) от начального значения -0.3 до 0.3 и обратно (yoyo: true), создавая циклическое движение. Цикл бесконечный (loop: -1`), длительность — 2 секунды, используется плавная синусоидальная функция easing.
this.tweens.add({
targets: fx,
x: 0.3,
yoyo: true,
loop: -1,
duration: 2000,
ease: 'sine.inout'
});
Что попробовать дальше
Комбинируя фильтр смещения, маски и твины, можно создавать сложные и живые визуальные эффекты с минимальным количеством кода. Для экспериментов попробуйте: использовать другую текстуру смещения (например, с более резкими перепадами), анимировать оба параметра `xиy` независимо, применить эффект к спрайту персонажа для создания "магической ауры" или использовать несколько фильтров смещения одновременно для более сложных искажений.
