О чем этот пример
Видео в играх может быть не просто фоном, а интерактивным элементом. Возможность динамической смены видео-источника открывает путь к созданию нелинейных кат-сцен, реактивных фонов или обучающих роликов, которые меняются в зависимости от действий игрока. В этой статье мы разберем, как загрузить несколько видео и переключаться между ними во время выполнения игры, используя метод `changeSource()` объекта `Phaser.GameObjects.Video`.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
this.intro;
this.debug;
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.video('mountains', 'assets/video/mountains.mp4', true);
this.load.video('pumpkins', 'assets/video/pumpkins.mp4', true);
}
create ()
{
// 960 x 540
this.intro = this.add.video(0, 0, 'pumpkins').setOrigin(0);
this.intro.on('locked', () => {
let message = this.add.text(480, 100, 'Click to play video', { font: '32px Courier', fill: '#00ff00' }).setShadow(1, 1).setOrigin(0.5);
this.intro.on('unlocked', () => {
message.destroy();
});
});
this.intro.play(true);
this.debug = this.add.text(10, 10, '', { font: '22px Courier', fill: '#ffffff' }).setShadow(1, 1);
// Listen for the 'play' event to create our input handler
this.intro.once('play', () => {
this.input.on('pointerdown', () => {
if (this.intro.getVideoKey() === 'pumpkins')
{
this.intro.changeSource('mountains', true, true);
}
else
{
this.intro.changeSource('pumpkins', true, true);
}
});
});
}
update ()
{
this.debug.setText([
'Current Time: ' + this.intro.getCurrentTime() + ' / ' + this.intro.getDuration(),
'Click to change video'
]);
}
}
const config = {
type: Phaser.AUTO,
width: 960,
height: 540,
backgroundColor: '#000000',
parent: 'phaser-example',
scene: Example
};
let game = new Phaser.Game(config);
Подготовка сцены и загрузка видео
Для работы с видео в Phaser необходимо создать класс сцены, который будет управлять их загрузкой и воспроизведением. Ключевой этап — предварительная загрузка всех необходимых видеофайлов в методe preload(). Это гарантирует, что контент будет доступен для мгновенного переключения.
В методе preload() используется this.load.video(). Параметр true в конце означает, что видео загрузится сразу, а не по запросу, что важно для плавной замены.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.video('mountains', 'assets/video/mountains.mp4', true);
this.load.video('pumpkins', 'assets/video/pumpkins.mp4', true);
}
После загрузки видео доступны в кеше под ключами 'mountains' и 'pumpkins'. Мы будем использовать эти ключи для их создания и смены.
Создание видеообъекта и обработка пользовательского ввода
В методе create() мы создаем экземпляр видео, размещаем его в начале координат и запускаем воспроизведение. Важный нюанс — воспроизведение видео в браузере часто требует жеста пользователя. Phaser предоставляет события 'locked' и 'unlocked' для обработки этой политики.
create ()
{
// 960 x 540
this.intro = this.add.video(0, 0, 'pumpkins').setOrigin(0);
this.intro.on('locked', () => {
let message = this.add.text(480, 100, 'Click to play video', { font: '32px Courier', fill: '#00ff00' }).setShadow(1, 1).setOrigin(0.5);
this.intro.on('unlocked', () => {
message.destroy();
});
});
this.intro.play(true);
}
Когда видео "разблокировано" (пользователь взаимодействовал со страницей), мы убираем текстовую подсказку и создаем обработчик клика мыши. Обратите внимание, что этот обработчик добавляется только после события 'play' видео, чтобы избежать преждевременных кликов.
Динамическая смена видео с помощью changeSource
Сердце примера — метод changeSource() объекта this.intro. Он позволяет заменить текущее видео на другое, уже загруженное в кеш, прямо во время выполнения.
this.input.on('pointerdown', () => {
if (this.intro.getVideoKey() === 'pumpkins')
{
this.intro.changeSource('mountains', true, true);
}
else
{
this.intro.changeSource('pumpkins', true, true);
}
});
В этом коде при каждом клике проверяется, какое видео сейчас играет (с помощью getVideoKey()), и на него подставляется альтернативное. Метод changeSource() принимает три аргумента: ключ нового видео, должен ли оно автоматически воспроизводиться (true), и должен ли сброситься текущий прогресс воспроизведения (true). Это позволяет мгновенно переключаться между роликами.
Отладка и отображение состояния видео
Для наглядности в примере реализован простой интерфейс отладки. В методе update() каждому кадру обновляется текстовое поле, отображающее текущее время воспроизведения и общую длительность видео.
update ()
{
this.debug.setText([
'Current Time: ' + this.intro.getCurrentTime() + ' / ' + this.intro.getDuration(),
'Click to change video'
]);
}
Здесь используются методы getCurrentTime() и getDuration() объекта this.intro. Такой подход полезен для тестирования и понимания того, как ведет себя видео при переключении. В реальном проекте эту информацию можно использовать, например, для синхронизации событий игры с конкретными моментами в видео.
Что попробовать дальше
Метод changeSource() превращает статичное видео в динамический игровой актив. Вы можете использовать этот подход для создания интерактивных инструкций, где следующий шаг объясняется в новом видео, или для фонов, реагирующих на смену уровня. Поэкспериментируйте: попробуйте переключать видео не по клику, а по таймеру или при столкновении игрока с объектом, добавьте плавное затемнение между переходами или используйте событие 'complete' одного видео для автоматического запуска следующего, создавая цепочку сцен.
