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

Создание плавных переходов между игровыми состояниями — важная часть игрового дизайна. Резкие смены сцены могут выбивать игрока из погружения. Встроенная система камер Phaser предоставляет простые, но мощные методы `fadeIn` и `fadeOut` для реализации кинематографичных затемнений и появлений. Эта статья покажет, как использовать эти методы для создания бесконечного цикла плавного перехода, который можно адаптировать для загрузки уровней, смены дня и ночи или драматичных событий.

Версия 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('robota', 'assets/pics/robota-uxo-by-made-of-bomb.jpg');
    }

    create ()
    {
        const image = this.add.image(900, 300, 'robota');

        this.tweens.add({
            targets: image,
            x: 100,
            ease: 'Sine.easeInOut',
            yoyo: true,
            repeat: -1,
            duration: 3000
        });

        this.cameras.main.once('camerafadeincomplete', function (camera) {
            camera.fadeOut(6000);
        });

        this.cameras.main.fadeIn(6000);
    }
}

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

const game = new Phaser.Game(config);

Основная логика примера

В данном примере реализован бесконечный цикл плавного появления (fade-in) и последующего исчезновения (fade-out) всей сцены. После загрузки изображения и запуска простой анимации камера начинает плавно проявлять сцену из чёрного цвета. Как только это действие завершается, автоматически запускается обратный процесс — затемнение сцены до чёрного.

Весь цикл управляется всего несколькими строчками кода, связанными с основным объектом камеры this.cameras.main.

Настройка анимации и камеры

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

const image = this.add.image(900, 300, 'robota');

this.tweens.add({
    targets: image,
    x: 100,
    ease: 'Sine.easeInOut',
    yoyo: true,
    repeat: -1,
    duration: 3000
});

Далее идёт ключевая часть: настройка обработчика события. Метод once гарантирует, что функция выполнится только один раз после завершения эффекта fadeIn. В этой функции мы инициируем обратный эффект.

this.cameras.main.once('camerafadeincomplete', function (camera) {
    camera.fadeOut(6000);
});

Наконец, непосредственно запускается первый эффект — постепенное проявление сцены в течение 6 секунд.

this.cameras.main.fadeIn(6000);

События камеры: camerafadeincomplete и camerafadeoutcomplete

Методы fadeIn() и fadeOut() являются асинхронными. Phaser генерирует события по их завершению, что позволяет выстраивать цепочки действий.

- camerafadeincomplete: генерируется, когда эффект полного появления завершён. В обработчик передаётся ссылка на объект камеры (camera). - camerafadeoutcomplete: генерируется по завершении полного затемнения.

Использование once() вместо on() в данном примере критично. Оно предотвращает бесконечное накопление обработчиков события, которое будет вызываться каждый цикл. Если заменить once на on, то с каждым новым циклом будет добавляться ещё один обработчик, что в итоге приведёт к ошибкам или неожиданному поведению.

Практическое применение и вариации

Такой паттерн «затухание -> действие -> появление» — основа для многих игровых механик.

1. **Переход между сценами:**

// В конце fadeOut переходим на новую сцену
    this.cameras.main.once('camerafadeoutcomplete', (camera) => {
        this.scene.start('NextLevel');
    });
    this.cameras.main.fadeOut(1000);

2. **Цвет затемнения:** По умолчанию используется чёрный цвет (0x000000). Его можно изменить, передав hex-код цвета вторым аргументом.

// Затемнение до кроваво-красного
    this.cameras.main.fadeOut(2000, 0xff0000);

3. **Внезапные события:** Короткое затемнение (fadeOut(200)) и немедленное появление (fadeIn(200)) можно использовать для эффекта «вспышки» при получении урона или использовании способности.

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

Методы fadeIn и fadeOut объекта камеры — это простой и эффективный способ добавить вашей игре кинематографичности и плавности. Они идеально подходят для переходов, введения в уровень или обозначения значимых событий. Для экспериментов попробуйте: создать цепочку из нескольких последовательных затемнений разными цветами; привязать начало эффекта к игровому событию (например, подбору предмета); или использовать camera.flash для быстрой белой вспышки, чтобы подчеркнуть момент взрыва.