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

Визуальные эффекты постобработки могут кардинально преобразить вашу игру, добавив глубины, атмосферы и профессионального лоска. Один из самых популярных и эффектных приёмов — свечение (bloom). В Phaser 3 он реализуется через систему камер и эффектов. Эта статья покажет, как с помощью `Phaser.Actions.AddEffectBloom` легко добавить динамическое свечение к вашей сцене, анимировать его параметры и создать гипнотический визуальный ряд.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    image;

    preload ()
    {
        
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('pic', 'assets/pics/the-end-by-iloe-and-made.jpg');
        this.load.image('phaser-logo', 'assets/sprites/phaser.png');
    }

    create ()
    {
        const image = this.add.image(640, 360, 'pic')
        .setScale(2);

        const text = this.add.text(160, 650, 'AddEffectBloom', { font: '32px Arial', fill: '#88ffff' })
        .setOrigin(0.5)
        .setScrollFactor(0);

        const phaserLogo = this.add.image(1120, 650, 'phaser-logo')
        .setScrollFactor(0);

        const { parallelFilters } = Phaser.Actions.AddEffectBloom(
            this.cameras.main,
            { blendAmount: 2 }
        );

        this.tweens.add({
            targets: parallelFilters.blend,
            amount: 0,
            duration: 1000,
            yoyo: true,
            repeat: -1,
            ease: 'Sine.easeInOut'
        });
    }

    update (time, _delta)
    {
        this.cameras.main.setScroll(
            512 * Math.cos(time / 5000),
            512 * Math.sin(time / 5000)
        );
    }
}

const config = {
    type: Phaser.WEBGL,
    width: 1280,
    height: 720,
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Загрузка ресурсов и базовая сцена

Первым делом, как и в любой сцене Phaser, мы загружаем необходимые ресурсы. В данном примере это фоновая картинка и логотип Phaser, которые будут использоваться в качестве визуальных элементов.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('pic', 'assets/pics/the-end-by-iloe-and-made.jpg');
    this.load.image('phaser-logo', 'assets/sprites/phaser.png');
}

В методе create создаётся основа сцены: фоновое изображение, статичный текст и логотип. Ключевой момент — метод setScrollFactor(0) для текста и логотипа. Это фиксирует их положение относительно экрана, делая независимыми от прокрутки камеры, которую мы будем анимировать позже.

create ()
{
    const image = this.add.image(640, 360, 'pic').setScale(2);
    const text = this.add.text(160, 650, 'AddEffectBloom', { font: '32px Arial', fill: '#88ffff' })
        .setOrigin(0.5)
        .setScrollFactor(0);
    const phaserLogo = this.add.image(1120, 650, 'phaser-logo').setScrollFactor(0);
    // ... Дальше будет эффект Bloom
}

Добавление эффекта Bloom на камеру

Сердце примера — вызов Phaser.Actions.AddEffectBloom. Этот статический метод применяет эффект свечения к указанной камере.

const { parallelFilters } = Phaser.Actions.AddEffectBloom(
    this.cameras.main,
    { blendAmount: 2 }
);
Разберём аргументы:
1.  `this.cameras.main` — целевая камера, к которой применяется эффект. В данном случае это основная камера сцены.
2.  `{ blendAmount: 2 }` — объект конфигурации. Параметр `blendAmount` определяет интенсивность смешения (наложения) эффекта свечения с исходным изображением. Значение `2` задаёт высокую начальную интенсивность.

Метод возвращает объект, из которого мы деструктурируем parallelFilters. Этот объект содержит ссылки на внутренние фильтры, управляющие эффектом, что позволяет нам анимировать их свойства.

Анимация параметра смешения (Blend Amount)

Чтобы эффект не был статичным, мы анимируем параметр amount фильтра смешения (blend), который находится внутри parallelFilters. Для этого идеально подходит система твинов Phaser.

this.tweens.add({
    targets: parallelFilters.blend,
    amount: 0,
    duration: 1000,
    yoyo: true,
    repeat: -1,
    ease: 'Sine.easeInOut'
});

Конфигурация твина: * targets: parallelFilters.blend — целевой объект, свойство которого мы будем изменять. * amount: 0 — целевое значение. Твин будет плавно менять blend.amount от исходного значения (вероятно, `2, как задано в конфиге) до0`. * duration: 1000 — длительность одного цикла анимации в миллисекундах. * yoyo: true — после достижения цели анимация пойдёт в обратном направлении. * repeat: -1 — бесконечное повторение цикла. * ease: 'Sine.easeInOut' — функция плавности, которая делает анимацию более естественной, с плавным ускорением и замедлением.

В результате интенсивность свечения будет пульсировать, создавая живой, дышащий эффект.

Динамическое движение камеры

Для демонстрации того, что эффект корректно применяется ко всей области видимости камеры, мы добавляем циклическое движение (прокрутку) в методе update.

update (time, _delta)
{
    this.cameras.main.setScroll(
        512 * Math.cos(time / 5000),
        512 * Math.sin(time / 5000)
    );
}

Здесь time — это общее время работы сцены в миллисекундах. Мы используем тригонометрические функции Math.cos и Math.sin для вычисления координат прокрутки по осям X и Y. Аргумент time / 5000 замедляет движение, делая полный круг примерно за 31.5 секунды. Эффект Bloom следует за камерой, обрабатывая только ту область игрового мира, которая в данный момент видна через её "объектив".

Что попробовать дальше

Всего несколько строк кода — и ваша сцена обретает профессиональный эффект свечения с плавной анимацией. Phaser.Actions.AddEffectBloom — мощный и простой инструмент для визуального обогащения игр. Для экспериментов попробуйте: изменить параметры в конфигурационном объекте (например, blendAmount, quality), анимировать другие свойства parallelFilters, применить эффект не к основной, а к дополнительной камере для создания слоистой композиции или комбинировать Bloom с другими эффектами постобработки, доступными в Phaser.