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

Визуальные эффекты (FX) — мощный инструмент для оживления игровых объектов. Phaser 3 предлагает две системы их применения: `preFX` и `postFX`. Понимание разницы между ними критически важно для создания корректных и производительных эффектов, особенно при изменении размера игрового окна. В этой статье мы разберем, как работают эти системы на конкретном примере с эффектом свечения (`Glow`) и почему их поведение различается.

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

Живой запуск

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

Исходный код


class GameScene extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('bomb', 'assets/sprites/bombcolor.png');
    }

    create ()
    {
        const bomb1 = this.add.image(200, 200, 'bomb');
        const bomb2 = this.add.image(500, 200, 'bomb');
        const bomb3 = this.add.image(800, 200, 'bomb');

        bomb1.preFX.addGlow(0x0000ff);

        bomb3.postFX.addGlow(0x00ff00);
    }
}

new Phaser.Game({
    type: Phaser.AUTO,
    scale: {
        mode: Phaser.Scale.RESIZE,
        parent: 'phaser-example',
        width: '100%',
        height: '100%'
    },
    scene: GameScene,
    parent: 'phaser-example'
});

Загрузка ресурсов и создание сцены

Первым делом в методе preload() мы настраиваем базовый URL для загрузки и подгружаем спрайт бомбы.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('bomb', 'assets/sprites/bombcolor.png');
}

В методе create() создаются три одинаковых спрайта, расположенных горизонтально. Именно к ним мы будем применять эффекты.

create ()
{
    const bomb1 = this.add.image(200, 200, 'bomb');
    const bomb2 = this.add.image(500, 200, 'bomb');
    const bomb3 = this.add.image(800, 200, 'bomb');
    // ... применение FX
}

Применение эффектов: preFX vs postFX

Ключевое действие происходит здесь. К первому спрайту (bomb1) применяется preFX, а к третьему (bomb3) — postFX. Второй спрайт (bomb2) остается без эффектов для наглядного сравнения.

bomb1.preFX.addGlow(0x0000ff); // Синее свечение (preFX)
bomb3.postFX.addGlow(0x00ff00); // Зеленое свечение (postFX)

preFX (предварительные эффекты) применяются к исходному текстуру объекта *до* его отрисовки на игровом холсте. postFX (пост-эффекты) применяются *после* того, как объект уже отрисован на холсте, как финальный проход. Это фундаментальное различие в порядке рендеринга.

Конфигурация игры и масштабирование

Конфигурация игры использует режим масштабирования Phaser.Scale.RESIZE. Это означает, что размер игрового холста будет автоматически подстраиваться под размеры своего родительского HTML-элемента.

new Phaser.Game({
    type: Phaser.AUTO,
    scale: {
        mode: Phaser.Scale.RESIZE,
        parent: 'phaser-example',
        width: '100%',
        height: '100%'
    },
    scene: GameScene,
    parent: 'phaser-example'
});

Режим RESIZE динамически меняет разрешение рендерера при изменении размеров окна браузера. Это поведение напрямую влияет на то, как будут выглядеть наши эффекты.

Практическое отличие: как ведут себя эффекты при RESIZE

Если запустить этот пример и изменить размер окна браузера, вы увидите разницу.

* **preFX (синее свечение на bomb1)**: Эффект привязан к самому игровому объекту (спрайту). При изменении размера окна и, следовательно, игрового холста, свечение масштабируется вместе со спрайтом. Оно является его неотъемлемой частью. * **postFX (зеленое свечение на bomb3)**: Эффект применяется к уже отрендеренному изображению объекта на холсте. При изменении размера холста (режим RESIZE) рендерер перерисовывает сцену в новом разрешении. Пост-эффект, который является отдельным проходом, может вести себя иначе — например, его интенсивность или размер могут зависеть от абсолютного разрешения, а не от относительного размера спрайта. В некоторых случаях это может привести к визуальным артефактам или неожиданному изменению вида эффекта.

Спрайт bomb2 без эффектов просто масштабируется, как и весь остальной контент сцены.

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

Выбор между preFX и postFX — это выбор между интеграцией эффекта в объект и его наложением как отдельного слоя. Используйте preFX для эффектов, которые должны быть неразрывно связаны с объектом и стабильно масштабироваться вместе с ним (например, свечение оружия, аура персонажа). postFX лучше подходит для глобальных эффектов экрана (например, размытие, цветокоррекция, виньетирование) или когда требуется особая производительность для сложных шейдеров. Поэкспериментируйте: попробуйте применить один и тот же эффект (например, размытие Blur) через оба конвейера и понаблюдайте за разницей в поведении при изменении размера окна или камеры.