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

Видео — мощный инструмент для создания интро, кат-сцен или динамического фона в играх. Важно не только проиграть ролик, но и отреагировать на его завершение: запустить следующий уровень, показать интерфейс или перезапустить видео по желанию игрока. В этом примере мы разберем, как использовать событие `complete` у видео (`Phaser.GameObjects.Video`), чтобы выполнить код после окончания воспроизведения. Этот подход заменяет ручной подсчет кадров и делает код чище и надежнее.

Версия 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.video('flight', 'assets/video/endless-flight.mp4', true);
    }

    create ()
    {
        const intro = this.add.video(400, 300, 'flight');

        intro.on('complete', () => {

            let message = this.add.text(400, 30, 'Video Completed - Click to restart', { font: '22px Courier', fill: '#ffffff' }).setOrigin(0.5);

            this.input.once('pointerdown', () => {

                message.destroy();

                intro.play();

            });

        });

        intro.play();
    }
}

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

let game = new Phaser.Game(config);

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

Работа с видео в Phaser начинается в методе preload. Мы используем this.load.video для загрузки видеофайла. Ключевой третий параметр true включает предварительную загрузку всего видео в память, что гарантирует плавное воспроизведение без буферизации.

После загрузки в методе create мы создаем объект видео с помощью this.add.video и размещаем его в центре экрана. Затем сразу запускаем воспроизведение методом play().

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.video('flight', 'assets/video/endless-flight.mp4', true);
}

create ()
{
    const intro = this.add.video(400, 300, 'flight');
    intro.play();
}

Обработка события окончания видео

Объект видео в Phaser — это Phaser.GameObjects.Video, который является наследником Phaser.Events.EventEmitter. Это значит, что он может генерировать и обрабатывать события. Одно из таких событий — complete, которое срабатывает, когда видео доигрывает до конца.

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

intro.on('complete', () => {
    let message = this.add.text(400, 30, 'Video Completed - Click to restart', { font: '22px Courier', fill: '#ffffff' }).setOrigin(0.5);
});

Рестарт видео по клику игрока

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

Внутри обработчика мы уничтожаем текстовое сообщение методом destroy() и снова запускаем видео через intro.play(). При повторном запуске событие complete снова будет работать, что позволяет циклически обрабатывать окончание ролика.

this.input.once('pointerdown', () => {
    message.destroy();
    intro.play();
});

Конфигурация игры и полный код

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

Полный код примера демонстрирует простую, но полноценную логику: загрузка, воспроизведение, реакция на окончание и интерактивный рестарт.

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

let game = new Phaser.Game(config);

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

Событие complete объекта Phaser.GameObjects.Video — это простой и эффективный способ синхронизировать игровую логику с окончанием видеоролика. Вы можете использовать этот механизм для переключения сцен, показа меню или активации игровых процессов. **Идеи для экспериментов:** Попробуйте вместо рестарта видео запускать другую сцену или проигрывать серию видео подряд, подписываясь на событие complete у каждого следующего ролика. Также можно добавить обработку события pause или looped для создания сложной видео-последовательности.