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

Управление камерой — ключевой навык при создании игр с прокруткой. В этом примере демонстрируется мощная комбинация: камера, которая автоматически следует за игроком, и возможность переключения на ручное управление её движением. Это полезно для создания кат-сцен, режимов осмотра карты или отладки игровых уровней. Мы разберем, как настроить границы мира, привязать камеру к спрайту и обрабатывать ввод для управления и персонажем, и видом камеры.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
        this.moveCam = false;
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        // this.load.image('bg', 'assets/pics/the-end-by-iloe-and-made.jpg');
        this.load.image('bg', 'assets/pics/backscroll.png');
        this.load.image('block', 'assets/sprites/crate32.png');
    }

    create ()
    {
        this.cameras.main.setBounds(0, 0, 720 * 2, 176);

        for (let x = 0; x < 2; x++)
        {
            this.add.image(720 * x, 0, 'bg').setOrigin(0);
        }

        this.cursors = this.input.keyboard.createCursorKeys();

        this.player = this.physics.add.image(400, 100, 'block');

        this.cameras.main.startFollow(this.player, true);
        this.cameras.main.setZoom(2);
    }

    update ()
    {
        const cam = this.cameras.main;

        this.player.setVelocity(0);

        if (this.moveCam)
        {
            if (this.cursors.left.isDown)
            {
                cam.scrollX -= 4;
            }
            else if (this.cursors.right.isDown)
            {
                cam.scrollX += 4;
            }

            if (this.cursors.up.isDown)
            {
                cam.scrollY -= 4;
            }
            else if (this.cursors.down.isDown)
            {
                cam.scrollY += 4;
            }
        }
        else
        {
            if (this.cursors.left.isDown)
            {
                this.player.setVelocityX(-400);
            }
            else if (this.cursors.right.isDown)
            {
                this.player.setVelocityX(400);
            }

            if (this.cursors.up.isDown)
            {
                this.player.setVelocityY(-400);
            }
            else if (this.cursors.down.isDown)
            {
                this.player.setVelocityY(400);
            }
        }
    }
}

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

var moveCam = false;

const game = new Phaser.Game(config);

Настройка сцены и загрузка

Класс сцены инициализирует флаг moveCam, который будет переключать режимы управления. В методе preload загружаются два изображения: фон и спрайт игрока. Обратите внимание на использование setBaseURL для удобного указания корневого пути к ресурсам.

class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
        this.moveCam = false;
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('bg', 'assets/pics/backscroll.png');
        this.load.image('block', 'assets/sprites/crate32.png');
    }

Создание мира и настройка камеры

В методе create происходит основная настройка. Сначала для главной камеры задаются границы мира с помощью setBounds. Это определяет область, за пределы которой камера не сможет выйти. Затем в цикле создаются два фоновых изображения, чтобы заполнить пространство мира, которое в два раза шире экрана. Создается физический спрайт игрока и объект cursors для отслеживания клавиш-стрелок. Ключевые моменты настройки камеры: 1. startFollow(this.player, true) — камера начинает плавно следовать за спрайтом игрока. Второй аргумент true включает линейную интерполяцию (Lerp) для более мягкого движения. 2. setZoom(2) — увеличивает масштаб камеры, чтобы крупнее показать игрока и его окружение.

create ()
{
    this.cameras.main.setBounds(0, 0, 720 * 2, 176);

    for (let x = 0; x < 2; x++)
    {
        this.add.image(720 * x, 0, 'bg').setOrigin(0);
    }

    this.cursors = this.input.keyboard.createCursorKeys();
    this.player = this.physics.add.image(400, 100, 'block');
    this.cameras.main.startFollow(this.player, true);
    this.cameras.main.setZoom(2);
}

Двойная логика управления в Update

Метод update содержит логику для двух режимов, переключаемых флагом this.moveCam. В начале кадра скорость игрока сбрасывается до нуля.

**Режим 1: Управление камерой (this.moveCam == true)** Когда флаг активен, нажатие стрелок изменяет свойства scrollX и scrollY главной камеры. Это приводит к ручному перемещению видимой области по миру, в то время как игрок остается на месте.

**Режим 2: Управление игроком (this.moveCam == false)** Это режим по умолчанию. Стрелки управляют скоростью игрока через setVelocityX и setVelocityY. Камера автоматически следует за движущимся игроком в пределах установленных границ.

update ()
{
    const cam = this.cameras.main;
    this.player.setVelocity(0);

    if (this.moveCam)
    {
        if (this.cursors.left.isDown) { cam.scrollX -= 4; }
        else if (this.cursors.right.isDown) { cam.scrollX += 4; }
        if (this.cursors.up.isDown) { cam.scrollY -= 4; }
        else if (this.cursors.down.isDown) { cam.scrollY += 4; }
    }
    else
    {
        if (this.cursors.left.isDown) { this.player.setVelocityX(-400); }
        else if (this.cursors.right.isDown) { this.player.setVelocityX(400); }
        if (this.cursors.up.isDown) { this.player.setVelocityY(-400); }
        else if (this.cursors.down.isDown) { this.player.setVelocityY(400); }
    }
}

Конфигурация игры и запуск

Конфигурационный объект config задает основные параметры игры. Важные настройки: - pixelArt: true — включает сглаживание текстуры для пиксель-арта. - physics.default: 'arcade' — активирует простую Arcade Physics. Переменная moveCam в глобальной области видимости (var moveCam = false) дублирует флаг из сцены и может быть переключена из консоли браузера для отладки. Экземпляр игры создается с этой конфигурацией.

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

var moveCam = false;
const game = new Phaser.Game(config);

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

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