О чем этот пример

Визуальные эффекты — ключ к созданию атмосферы и динамики в играх. Фильтр смещения (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). Попробуйте применить его к спрайтам персонажей для эффекта шагохода или к фону уровня для имитации подводных течений.