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

Игроки заходят в вашу игру с мониторов, ноутбуков, планшетов и телефонов. У каждого устройства свое разрешение и соотношение сторон. Если не продумать адаптацию под разные экраны, игра может оказаться растянутой, обрезанной или с пустыми черными полями по краям. Конфигурация масштабирования в Phaser 3 решает эту проблему. Используя режим `Phaser.Scale.FIT` вместе с `Phaser.Scale.CENTER_BOTH`, вы гарантируете, что игровое поле всегда будет целиком умещаться на экране пользователя, сохраняя свои пропорции и автоматически центрируясь. Это базовый и надежный подход для большинства игр, который мы и разберем в статье.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('pic', 'assets/pics/zero-two.png');
    }

    create ()
    {
        this.add.image(0, 0, 'pic').setOrigin(0);
    }
}

const config = {
    type: Phaser.AUTO,
    backgroundColor: '#2dab2d',
    scale: {
        parent: 'phaser-example',
        mode: Phaser.Scale.FIT,
        autoCenter: Phaser.Scale.CENTER_BOTH,
        width: 800,
        height: 600
    },
    scene: Example
};

const game = new Phaser.Game(config);

Сердце настройки: объект `scale` в конфиге

Вся магия адаптивного отображения запускается в конфигурационном объекте, который передается конструктору new Phaser.Game(). Ключевой раздел здесь — scale.

const config = {
    type: Phaser.AUTO,
    backgroundColor: '#2dab2d',
    scale: {
        parent: 'phaser-example',
        mode: Phaser.Scale.FIT,
        autoCenter: Phaser.Scale.CENTER_BOTH,
        width: 800,
        height: 600
    },
    scene: Example
};

Параметры width и height задают внутреннее, «игровое» разрешение вашего проекта. В данном случае это 800x600 пикселей. Именно в этой координатной сетке вы будете расставлять объекты. Далее Phaser будет подгонять эту область под экран устройства согласно выбранному mode.

Режим `FIT`: сохраняем пропорции любой ценой

Режим Phaser.Scale.FIT — это самый «безопасный» вариант. Его логика проста: игровая область (800x600) должна быть показана целиком, без обрезки, на любом экране.

mode: Phaser.Scale.FIT

Phaser вычисляет коэффициент масштабирования отдельно для ширины и высоты, чтобы игровая область вписалась в доступное пространство. Затем он выбирает меньший из этих коэффициентов. Это гарантирует, что вся область видна, но может привести к появлению пустых полей (полей письма) сверху и снизу или слева и справа, если пропорции экрана и игры не совпадают. Цвет этих полей определяется backgroundColor в основном конфиге.

Автоцентрирование `CENTER_BOTH`: игра по центру экрана

Когда появляются пустые поля, встает вопрос об их расположении. Параметр autoCenter управляет именно этим.

autoCenter: Phaser.Scale.CENTER_BOTH

Значение CENTER_BOTH означает центрирование и по горизонтали, и по вертикали. Игровая область будет отрисована ровно посередине родительского контейнера (в данном случае — элемента с id='phaser-example'). Это самый эстетичный и предсказуемый вариант, который создает у игрока ощущение законченного, оформленного продукта.

Как это работает внутри сцены

Важно понимать, что все расчеты масштабирования и позиционирования Phaser берет на себя. Внутри сцены вы работаете с вашим «родным» разрешением (800x600), как будто игра всегда запущена в этом размере.

create ()
{
    this.add.image(0, 0, 'pic').setOrigin(0);
}

В этом примере изображение 'pic' помещается в точку (0, 0) — верхний левый угол игрового мира. Благодаря setOrigin(0), точка привязки изображения тоже устанавливается в его левый верхний угол. Независимо от того, на каком экране запущена игра, это изображение всегда будет находиться в левом верхнем углу игровой области 800x600, которая, в свою очередь, будет отмасштабирована и отцентрирована на реальном экране.

Роль `parent` и настройка контейнера

Параметр parent связывает экземпляр Phaser Game с конкретным элементом DOM.

parent: 'phaser-example'

Этот код ищет в HTML-документе элемент с атрибутом id="phaser-example" (например, <div id="phaser-example"></div>) и использует его как контейнер для canvas. Размеры и положение этого контейнера (которые можно задать через CSS) становятся доступным пространством, под которое Phaser будет подгонять игровую область согласно правилам FIT. Если parent не указан, игра будет привязана к телу документа (body).

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

Комбинация Phaser.Scale.FIT и CENTER_BOTH — это ваш надежный фундамент для создания игры, которая корректно выглядит на большинстве устройств. Она избавляет от обрезанного контента и искажений, жертвуя лишь возможным заполнением полей фоновым цветом. Для экспериментов попробуйте: 1. Изменить mode на Phaser.Scale.RESIZE и посмотреть, как игра растягивается на весь экран, меняя внутреннюю систему координат. 2. Заменить CENTER_BOTH на CENTER_HORIZONTALLY и посмотреть, как игровая область прижмется к верхнему краю. 3. Поиграть с CSS-свойствами (размерами, padding) контейнера #phaser-example и увидеть, как Phaser мгновенно пересчитывает макет.