О чем этот пример
Видео — это мощный инструмент для создания атмосферы и динамичных сцен в играх. Phaser 3 позволяет легко загружать и воспроизводить несколько видеофайлов одновременно, что открывает двери для таких эффектов, как видеостены, мониторы наблюдения или сложные фоновые композиции. В этой статье мы разберем пример, где четыре видео воспроизводятся в разных частях экрана, и научимся управлять их размерами и поведением.
Версия 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('fireworks', 'assets/video/fireworks.mp4', true);
this.load.video('pumpkins', 'assets/video/pumpkins.mp4', true);
this.load.video('underwater', 'assets/video/underwater.mp4', true);
this.load.video('river', 'assets/video/river.mp4', true);
}
create ()
{
const vid1 = this.add.video(0, 0, 'pumpkins').setOrigin(0, 0).play(true);
vid1.once('play', () => {
vid1.setDisplaySize(400, 300);
});
const vid2 = this.add.video(400, 0, 'fireworks').setOrigin(0, 0).play(true);
vid2.once('play', () => {
vid2.setDisplaySize(400, 300);
});
const vid3 = this.add.video(0, 300, 'underwater').setOrigin(0, 0).play(true);
vid3.once('play', () => {
vid3.setDisplaySize(400, 300);
});
const vid4 = this.add.video(400, 300, 'river').setOrigin(0, 0).play(true);
vid4.once('play', () => {
vid4.setDisplaySize(400, 300);
});
}
}
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(), который принимает три ключевых аргумента: уникальный ключ для последующего обращения, путь к файлу и флаг loadEvent (в данном случае true, что означает стандартную загрузку через событие loadeddata).
this.load.video('fireworks', 'assets/video/fireworks.mp4', true);
this.load.video('pumpkins', 'assets/video/pumpkins.mp4', true);
this.load.video('underwater', 'assets/video/underwater.mp4', true);
this.load.video('river', 'assets/video/river.mp4', true);
Обратите внимание, что setBaseURL задает базовый путь, к которому будут добавляться относительные пути к видео. Это удобно для структурирования ресурсов.
Создание и размещение видеообъектов
Создание видео на сцене происходит в методе create() с помощью this.add.video(). Метод принимает координаты X, Y и ключ загруженного видео. Сразу после создания можно вызвать цепочку методов для настройки.
const vid1 = this.add.video(0, 0, 'pumpkins').setOrigin(0, 0).play(true);
Здесь мы:
1. Создаем видео vid1 в точке (0,0) с ключом 'pumpkins'.
2. setOrigin(0, 0) — устанавливаем точку привязки (origin) в левый верхний угол видео. Это важно для точного позиционирования, так как по умолчанию origin находится в центре объекта.
3. play(true) — немедленно начинаем воспроизведение. Аргумент true указывает на зацикливание (loop).
Таким же образом создаются остальные три видео, образуя сетку 2x2.
Динамическое изменение размера
Если установить размер видео сразу после создания, оно может отобразиться некорректно, так как метаданные (например, исходные ширина и высота) могут быть еще не доступны. Поэтому изменение размера лучше привязать к событию начала воспроизведения play.
vid1.once('play', () => {
vid1.setDisplaySize(400, 300);
});
Мы используем метод once, чтобы обработчик сработал только при первом запуске видео. Внутри колбэка вызывается setDisplaySize(400, 300), который масштабирует видео до ширины 400 и высоты 300 пикселей, подгоняя его под размер ячейки нашей сетки.
Этот подход гарантирует, что размер изменится только после того, как видео будет готово к отображению.
Конфигурация игры и сцены
Ключевой момент — передача нашего класса сцены Example в конфигурацию игры. Также важно задать размер холста (width, height) и цвет фона.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
parent: 'phaser-example',
scene: Example
};
let game = new Phaser.Game(config);
Поскольку каждое видео имеет размер 400x300, а общий размер холста — 800x600, четыре видео идеально заполняют экран без перекрытий. Черный фон (#000000) может быть виден только в случае, если видео не покрывают всю область.
Что попробовать дальше
Работа с несколькими видео в Phaser 3 сводится к их загрузке, созданию объектов и управлению через события. Этот пример демонстрирует базовый паттерн для создания видеостен. Для экспериментов попробуйте: добавить элементы управления (пауза, громкость) для каждого видео отдельно; реализовать плавное переключение видео в одной ячейке; использовать прозрачность (setAlpha) для наложения видео друг на друга; или привязать воспроизведение видео к игровым событиям.
