О чем этот пример
Визуальные эффекты — ключ к созданию атмосферы и динамики в играх. Фильтр смещения (Displacement Filter) позволяет искажать текстуры с помощью карты шума, создавая эффекты воды, теплового марева, волн или психоделических переходов. Этот пример демонстрирует, как в Phaser 3 с помощью нескольких строк кода добавить на статичную картинку анимированное, пульсирующее искажение, которое можно использовать для порталов, магических заклинаний или искажённой реальности.
Версия 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/taikodrummaster.jpg');
this.load.image('distort', 'assets/tests/noisesmall.png');
}
create ()
{
const pic = this.add.image(400, 300, 'pic');
const fx = pic.enableFilters().filters.internal.addDisplacement('distort', -0.03, -0.03);
this.tweens.add({
targets: fx,
x: 0.03,
y: 0.03,
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);
Загрузка ресурсов для эффекта
Для работы фильтра смещения необходимы два изображения. Основное — это текстура, которую мы будем искажать. Второе — карта смещения (displacement map), обычно представляющая собой текстуру шума (например, черно-белый шум Перлина). Яркость пикселей на этой карте определяет направление и силу смещения соответствующих пикселей основного изображения.
В методе preload мы загружаем оба изображения, используя удобный метод setBaseURL, чтобы не указывать полный путь для каждого файла.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('pic', 'assets/pics/taikodrummaster.jpg');
this.load.image('distort', 'assets/tests/noisesmall.png');
}
Создание изображения и добавление фильтра
В методе create мы сначала добавляем основное изображение на сцену. Ключевой шаг — включение системы фильтров для этого игрового объекта с помощью метода enableFilters(). После этого мы получаем доступ к менеджеру фильтров объекта filters.internal и добавляем фильтр смещения.
Метод addDisplacement принимает ключ текстуры карты смещения ('distort') и начальные значения для свойств `xиy`. Эти свойства управляют масштабом смещения по осям. Отрицательные и положительные значения смещают пиксели в разные стороны.
const pic = this.add.image(400, 300, 'pic');
const fx = pic.enableFilters().filters.internal.addDisplacement('distort', -0.03, -0.03);
Анимация эффекта через Tween
Статичное искажение — это уже интересно, но анимация делает эффект по-настоящему живым. Мы используем систему Tween Phaser для плавного изменения значений `xиyфильтра. Эти свойства анимируются от начальных значений (-0.03) до 0.03 и обратно (благодаря флагуyoyo: true`).
Параметр loop: -1 заставляет анимацию повторяться бесконечно, создавая непрерывный пульсирующий эффект. Длительность (duration) и функция плавности (ease) контролируют характер движения.
this.tweens.add({
targets: fx,
x: 0.03,
y: 0.03,
yoyo: true,
loop: -1,
duration: 2000,
ease: 'sine.inout'
});
Настройка сцены и запуск игры
Это стандартная конфигурация для примера Phaser. В объекте config мы определяем тип рендерера, размеры холста, цвет фона и указываем, какой класс является главной сценой. После создания экземпляра Phaser.Game с этой конфигурацией игра запускается.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Фильтр смещения — мощный и относительно простой в использовании инструмент для создания сложных визуальных искажений. Вы можете экспериментировать с разными текстурами для карты смещения (например, с радиальным градиентом или полосатым узором), анимировать не только общий масштаб, но и саму карту (например, её положение filter.scrollX), или комбинировать этот фильтр с другими, например, с размытием (BlurFXFilter) или свечением (GlowFilter). Попробуйте применить его к спрайтам персонажей для эффекта шагохода или к фону уровня для имитации подводных течений.
