О чем этот пример
Работа с камерами — это один из ключевых навыков для создания сложных игровых сцен в Phaser. Часто одной камеры на всю сцену бывает недостаточно. Представьте игру с разделённым экраном для двух игроков, миникарту в углу или сложный UI, который должен оставаться статичным поверх игрового мира. Всё это реализуется с помощью системы камер Phaser. В этой статье мы разберём пример, который демонстрирует создание четырёх независимых камер, каждая из которых отображает одну и ту же сцену, но в своей части экрана. Вы научитесь настраивать их размер, положение, фон и управлять отображаемыми объектами, открывая путь к созданию продвинутых визуальных эффектов и интерфейсов.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class MainScene extends Phaser.Scene
{
constructor()
{
super({ key: "MainScene" });
}
init() {
this.cameras.main.setSize(400, 300).setName('1').setBackgroundColor(0xff0000);
this.cameras.add(400, 0, 400, 300).setName('2').setBackgroundColor(0x00ffff);
this.cameras.add(0, 300, 400, 300).setName('3').setBackgroundColor(0x0000ff);
this.cameras.add(400, 300, 400, 300).setName('4').setBackgroundColor(0xffff00);
}
preload() {
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image("earth", "assets/pics/ayu.png");
this.load.scripts('inspector', [
'https://cdn.jsdelivr.net/npm/tweakpane@3.1.0',
'https://cdn.jsdelivr.net/npm/phaser-plugin-inspector@2.4.1',
]);
}
create ()
{
this.earth = this.add.image(200, 150, "earth");
// const gui = new dat.GUI();
// for (let i = 0; i < this.cameras.cameras.length; i++)
// {
// const camera = this.cameras.cameras[ i ];
// gui.add(camera, 'alpha', 0.1, 1).step(0.1);
// }
}
update (time)
{
this.earth.rotation += 0.005;
this.earth.y = this.earth.y + Math.sin(time / 1000 * 2)
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
pixelArt: true,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH
},
scene: [ MainScene ]
};
const game = new Phaser.Game(config);
Настройка основной и дополнительных камер
В Phaser каждая сцена (Scene) по умолчанию имеет одну главную камеру, доступную через this.cameras.main. Её свойства можно изменять. В методе init() нашего примера происходит первоначальная настройка.
Сначала мы меняем размер и фон главной камеры. Затем создаём три дополнительные камеры. Метод this.cameras.add() принимает координаты X, Y, ширину и высоту новой области просмотра. Каждой камере задаётся уникальное имя и цвет фона для наглядности.
init() {
this.cameras.main.setSize(400, 300).setName('1').setBackgroundColor(0xff0000);
this.cameras.add(400, 0, 400, 300).setName('2').setBackgroundColor(0x00ffff);
this.cameras.add(0, 300, 400, 300).setName('3').setBackgroundColor(0x0000ff);
this.cameras.add(400, 300, 400, 300).setName('4').setBackgroundColor(0xffff00);
}
В результате мы получаем экран 800x600, разделённый на четыре квадранта по 400x300 пикселей каждый, со своей камерой в каждом. Цвет фона (setBackgroundColor) виден только там, где нет игровых объектов.
Создание и анимация общего объекта
Несмотря на то что камеры четыре, игровой мир — один. Объекты, добавленные в сцену, будут отображаться во всех камерах одновременно, если не заданы специальные фильтры.
В методе create() мы создаём один-единственный спрайт — изображение Земли. Обратите внимание: он добавляется в координатах (200, 150) относительно мировых координат сцены. Поскольку главная камера (камера №1) теперь смотрит только на область (0,0,400,300) мировых координат, этот спрайт окажется в её центре. Для остальных камер он будет находиться в одном и том же мировом положении.
create ()
{
this.earth = this.add.image(200, 150, "earth");
}
В методе update() этому спрайту добавляется простая анимация: постоянное вращение и плавное движение по вертикали с использованием синуса. Эти изменения применяются к самому объекту this.earth и автоматически видны во всех четырёх областях просмотра.
update (time)
{
this.earth.rotation += 0.005;
this.earth.y = this.earth.y + Math.sin(time / 1000 * 2)
}
Конфигурация игры и масштабирование
Важную роль играет настройка масштабирования (scale) в конфигурационном объекте игры. В примере используется режим Phaser.Scale.FIT, который гарантирует, что игровая область (800x600) будет вписана в окно браузера с сохранением пропорций. Phaser.Scale.CENTER_BOTH центрирует отрисованную область по горизонтали и вертикали.
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
pixelArt: true,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH
},
scene: [ MainScene ]
};
Благодаря этим настройкам, даже если физический размер окна браузера изменится, сетка из четырёх камер останется корректной и пропорциональной. Флаг pixelArt: true включает специальное сглаживание для пиксельной графики, что может быть полезно для ретро-стиля.
Практическое применение и контроль
Зачем создавать несколько камер? Вот несколько сценариев:
* **Split-Screen (разделённый экран)**: Каждая камера следует за своим игроком в кооперативной игре.
* **Миникарта**: Одна камера показывает общий вид уровня в углу экрана.
* **Статичный UI**: Интерфейс (здоровье, боезапас) можно отрисовывать в отдельной камере, которая не подвержена встряскам (shake) или скроллу основной камеры.
* **Эффекты зеркал или видеонаблюдения**: Камера может быть направлена на другую часть сцены и отрисована на текстуре.
Каждой камерой можно управлять независимо. Вы можете:
* **Менять её область просмотра в мире** с помощью setScroll.
* **Применять визуальные эффекты**: setAlpha (прозрачность), setZoom (масштаб), setRotation (вращение).
* **Назначавать объекты конкретным камерам**, чтобы они были видны только в них, используя свойство visible объекта и методы камеры ignore.
Закомментированный код в примере намекает на возможность динамического изменения прозрачности (alpha) каждой камеры через панель отладки.
Что попробовать дальше
Система камер в Phaser — это мощный и гибкий инструмент, выходящий далеко за рамки простого следования за игроком. Разделение экрана на несколько независимых областей просмотра открывает возможности для сложных механик и улучшения пользовательского опыта.
**Идеи для экспериментов:**
1. Заставьте каждую камеру следовать за отдельным спрайтом, создав простой split-screen.
2. Поэкспериментируйте с эффектами камер: добавьте setZoom к одной и setRotation к другой в цикле update.
3. Создайте объект (например, снаряд) и сделайте его видимым только для одной из камер с помощью camera.ignore(this.bullet) для остальных.
