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

Плавные переходы между игровыми состояниями или визуальные эффекты затемнения — ключевые элементы для создания атмосферы и управления вниманием игрока. В Phaser 3 камера предоставляет мощные встроенные инструменты для таких задач. Эта статья на практическом примере разберет, как использовать эффект плавного затемнения (`fade`) камеры и связывать его с другими игровыми событиями, например, показом UI-элементов в точные моменты времени.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('pic', 'assets/pics/a-new-link-to-the-past-by-ptimm.jpg');
        this.load.image('logo', 'assets/sprites/phaser3-logo.png');
    }

    create ()
    {
        this.add.image(400, 300, 'pic');

        this.logo = this.add.image(400, 200, 'logo')
            .setVisible(false);

        //  Let's show the logo when the camera shakes, and hide it when it completes
        this.cameras.main.on('camerafadeoutstart', function () {

            this.logo.setVisible(true);

        }, this);

        this.cameras.main.on('camerafadeoutcomplete', function () {

            this.logo.setVisible(false);

        }, this);

        //  Every time you click, fade the camera
        this.input.on('pointerdown', function () {

            //  Get a random color
            var red = Phaser.Math.Between(50, 255);
            var green = Phaser.Math.Between(50, 255);
            var blue = Phaser.Math.Between(50, 255);

            this.cameras.main.fade(2000, red, green, blue);

        }, this);
    }
}

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: Example
};

const game = new Phaser.Game(config);

Настройка сцены и загрузка ресурсов

Класс сцены Example расширяет Phaser.Scene. В методе preload задается базовый URL для загрузки и загружаются два изображения: фоновая картинка (pic) и логотип (logo), который изначально будет скрыт.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('pic', 'assets/pics/a-new-link-to-the-past-by-ptimm.jpg');
    this.load.image('logo', 'assets/sprites/phaser3-logo.png');
}

Создание объектов и подписка на события камеры

В методе create сначала добавляется фоновое изображение. Затем создается спрайт логотипа, но он сразу делается невидимым с помощью метода .setVisible(false). Это важный шаг для последующего контроля его появления.

this.add.image(400, 300, 'pic');

this.logo = this.add.image(400, 200, 'logo')
    .setVisible(false);

Далее настраивается реакция на события камеры. Объект основной камеры доступен через this.cameras.main. У него есть события, связанные с эффектом затухания. Мы подписываемся на событие начала затемнения (camerafadeoutstart), чтобы показать логотип, и на событие завершения затемнения (camerafadeoutcomplete), чтобы снова его скрыть. Контекст this передается третьим аргументом, чтобы внутри функций-обработчиков сохранялась ссылка на сцену.

this.cameras.main.on('camerafadeoutstart', function () {
    this.logo.setVisible(true);
}, this);

this.cameras.main.on('camerafadeoutcomplete', function () {
    this.logo.setVisible(false);
}, this);

Запуск эффекта fade по клику

Теперь нужно инициировать сам эффект. В примере это происходит по клику (или касанию). На событие pointerdown от системы ввода (this.input) вешается обработчик.

this.input.on('pointerdown', function () {
    //  Get a random color
    var red = Phaser.Math.Between(50, 255);
    var green = Phaser.Math.Between(50, 255);
    var blue = Phaser.Math.Between(50, 255);

    this.cameras.main.fade(2000, red, green, blue);
}, this);

Внутри обработчика генерируется случайный цвет для эффекта с помощью Phaser.Math.Between. Затем вызывается метод this.cameras.main.fade(). Первый аргумент (2000) — это длительность эффекта в миллисекундах. Следующие три аргумента — компоненты цвета (RGB), в который будет плавно переходить изображение на камере.

Инициализация игры

За пределами класса сцены создается конфигурационный объект config для игры. В нем указывается автоматический выбор рендерера, родительский DOM-элемент, размеры холста и класс сцены по умолчанию.

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: Example
};

Финальный шаг — создание экземпляра игры с этой конфигурацией.

const game = new Phaser.Game(config);

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

Эффекты камеры, такие как fade, — это простой, но мощный способ добавить вашей игре полировки. Механизм событий (camerafadeoutstart, camerafadeoutcomplete) позволяет точно синхронизировать логику игры (показ/скрытие интерфейса, запуск диалога, переход на новую сцену) с визуальным переходом. Для экспериментов попробуйте: использовать метод camera.flash для вспышки, запускать fade не по клику, а по таймеру или при столкновении объектов, или создать цепочку из нескольких последовательных эффектов fade и flash для сложной cinematic-последовательности.