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

Работа с одной основной камерой — это стандарт для большинства игр. Но что, если вам нужно показать несколько разных ракурсов или областей игры одновременно? Возможно, для реализации камер наблюдения, сплит-скрина для нескольких игроков или сложного UI. Phaser позволяет создавать и управлять множеством камер. В этой статье мы разберём, как динамически добавлять камеры по щелчку мыши, формируя из них аккуратную сетку. Этот приём даст вам контроль над отображением разных частей игрового мира в реальном времени.

Версия 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('einstein', 'assets/pics/ra-einstein.png');
    }

    create ()
    {
        this.image = this.add.image(100, 70, 'einstein');

        //  We're going to create 32 cameras in a 8x4 grid each time you click, making each 100x150 in size

        this.cameras.main.setSize(100, 150);

        let x = 100;
        let y = 0;

        this.input.on('pointerup', function () {

            if (this.cameras.getTotal() < 32)
            {
                this.cameras.add(x, y, 100, 150);

                x += 100;

                if (x === 800)
                {
                    x = 0;
                    y += 150;
                }
            }

        }, this);
    }

    update ()
    {
        this.image.rotation += 0.01;
    }
}

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

const game = new Phaser.Game(config);

Загрузка ассета и настройка основной камеры

В методе preload загружается изображение, которое будет служить визуальным маркером в нашей сцене. В create это изображение добавляется на сцену.

Более важный шаг — изменение размера основной камеры (this.cameras.main). По умолчанию она занимает весь игровой холст. Мы же явно задаём ей меньший размер, освобождая место для других камер.

this.cameras.main.setSize(100, 150);

Эта строка изменяет область просмотра *основной* камеры. Теперь она будет отображать игровой мир только в прямоугольнике размером 100x150 пикселей в левом верхнем углу холста. Всё, что находится за пределами этой области, основной камерой отображаться не будет, но останется в игровом мире.

Динамическое добавление камер по клику

Логика добавления новых камер привязана к событию клика (pointerup). Мы создаём сетку 8x4, то есть максимум 32 камеры.

this.input.on('pointerup', function () {
    if (this.cameras.getTotal() < 32) {
        this.cameras.add(x, y, 100, 150);
        x += 100;
        if (x === 800) {
            x = 0;
            y += 150;
        }
    }
}, this);

Обратите внимание: метод this.cameras.add(x, y, 100, 150) создаёт новую камеру. Параметры `xиy— это координаты на *игровом холсте*, где будет расположен её видпорт (область отрисовки). Параметры100, 150` — это размер этой области.

Переменные `xиyуправляют позиционированием. Камеры добавляются слева направо (x += 100), а когда строка заполнена (x === 800), курсор сбрасывается в начало следующей строки (x = 0; y += 150). Условиеthis.cameras.getTotal() < 32` не даёт создать больше камер, чем вмещает наша сетка.

Разница между координатами камеры и игрового мира

Ключевой момент — понимание двух систем координат. В нашем примере есть вращающееся изображение Эйнштейна.

this.image.rotation += 0.01;

Это изменение происходит в *игровом мире*. Все созданные камеры смотрят на один и тот же игровой мир. Поскольку их видпорты (области отрисовки) расположены на холсте в разных местах, каждая из них показывает один и тот же вращающийся спрайт, но под своим уникальным "углом зрения" на холсте. Основная камера — такая же, как и все добавленные, просто созданная по умолчанию. Все они равноправно рендерят одну сцену.

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

Конфигурация игры задаёт общий размер холста 800x600. Наша логика добавления камер идеально вписывается в эти размеры, создавая сетку 8x4 камер размером 100x150.

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

Такой подход можно адаптировать для: * **Сплит-скрина:** Создать 2 или 4 камеры, каждая из которых следует за своим игроком. * **Миникарты:** Одна камера (основная) показывает основной вид, а вторая, маленькая, привязана к верху экрана и показывает всю карту. * **Статические виды:** Несколько камер, закреплённых за разными важными областями уровня (например, за дверьми или ловушками). Важно помнить, что каждая камера — это не отдельный объект, а "окно" в общий игровой мир. Изменения в мире видны во всех активных камерах.

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

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