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

Управление камерой — ключевой навык для создания игр с большими уровнями или прокруткой. Метод `centerOn()` позволяет легко перемещать видимую область, фокусируясь на нужных точках мира. Эта статья объяснит, как работает центрирование, и покажет практический пример переключения между предустановленными позициями по клику мыши, что полезно для кат-сцен, карт или навигации по локациям.

Версия 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('map', 'assets/tests/camera/earthbound-scarab.png');
    }

    create ()
    {
        this.cameras.main.setBounds(0, 0, 1024, 2048);

        this.add.image(0, 0, 'map').setOrigin(0);

        this.cameras.main.setZoom(4);
        this.cameras.main.centerOn(0, 0);

        const text = this.add.text(304, 230).setText('Click to move').setScrollFactor(0);
        text.setShadow(1, 1, '#000000', 2);

        let pos = 0;

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

            const cam = this.cameras.main;

            if (pos === 0)
            {
                cam.centerOn(767, 1096);
                pos++;
            }
            else if (pos === 1)
            {
                cam.centerOn(703, 1621);
                pos++;
            }
            else if (pos === 2)
            {
                cam.centerOn(256, 623);
                pos++;
            }
            else if (pos === 3)
            {
                cam.centerOn(166, 304);
                pos++;
            }
            else if (pos === 4)
            {
                cam.centerOn(624, 158);
                pos++;
            }
            else if (pos === 5)
            {
                cam.centerOn(680, 330);
                pos++;
            }
            else if (pos === 6)
            {
                cam.centerOn(748, 488);
                pos++;
            }
            else if (pos === 7)
            {
                cam.centerOn(1003, 1719);
                pos = 0;
            }

            text.setText(['Click to move', 'x: ' + cam.scrollX, 'y: ' + cam.scrollY ]);

        }, this);
    }
}

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

const game = new Phaser.Game(config);

Подготовка сцены и установка границ

Первым делом в методе create() мы задаем границы, за которые камера не сможет выйти. Это особенно важно для больших карт.

this.cameras.main.setBounds(0, 0, 1024, 2048);

Затем мы добавляем само изображение карты в начало координат игрового мира (0, 0). Метод setOrigin(0) фиксирует точку привязки спрайта в его верхнем левом углу.

this.add.image(0, 0, 'map').setOrigin(0);

Далее мы устанавливаем увеличение камеры в 4 раза, чтобы рассмотреть детали, и центрируем ее на начальной точке мира (0, 0).

this.cameras.main.setZoom(4);
this.cameras.main.centerOn(0, 0);

Как работает метод centerOn()

Метод centerOn(x, y) — это инструмент для управления scrollX и scrollY камеры. Он перемещает точку центрирования (изначально — центр окна просмотра) на указанные мировые координаты `xиy`. В результате эти координаты окажутся в центре экрана игрока.

В нашем примере при первом клике вызывается:

cam.centerOn(767, 1096);

Это мгновенно перемещает камеру так, чтобы мировая точка (767, 1096) оказалась по центру экрана. Метод автоматически учитывает текущий зум и границы камеры, установленные ранее через setBounds().

Обработка ввода и цикл позиций

Для интерактивности мы добавляем обработчик события клика мыши (pointerdown). Внутри используется простая переменная-счетчик pos для циклического перебора восьми предзаданных точек на карте.

let pos = 0;
this.input.on('pointerdown', function () {
    const cam = this.cameras.main;
    if (pos === 0) {
        cam.centerOn(767, 1096);
        pos++;
    }
    // ... остальные условия для pos от 1 до 7
}, this);

После каждого перемещения мы также обновляем текстовый объект, чтобы отобразить новые координаты прокрутки камеры (scrollX, scrollY). Важно отметить, что setScrollFactor(0) закрепляет этот текст относительно экрана, а не игрового мира.

text.setText(['Click to move', 'x: ' + cam.scrollX, 'y: ' + cam.scrollY]);

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

Метод centerOn() — это простой и мощный способ управления камерой для резкой смены ракурса. Для экспериментов попробуйте: заменить резкий переход на плавную интерполяцию с помощью pan(); привязать центрирование к движению игрового персонажа; создать систему маркеров на карте, по клику на которые камера будет перемещаться к соответствующей точке мира.