Центрирование игры в браузере

Phaser — это мощная библиотека для создания 2D-игр на JavaScript. Одной из частых задач при разработке браузерных игр является правильная центровка игрового окна на экране пользователя, чтобы игра корректно отображалась на разных разрешениях и устройствах.


Конфигурация игрового объекта

Основной способ управления размером и положением игры в Phaser — через объект конфигурации при создании экземпляра Phaser.Game:

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'game-container',
    scale: {
        mode: Phaser.Scale.FIT,
        autoCenter: Phaser.Scale.CENTER_BOTH
    },
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

const game = new Phaser.Game(config);
  • type — определяет рендерер: Phaser.AUTO выбирает между Canvas и WebGL.
  • width/height — исходные размеры игры.
  • parent — идентификатор контейнера в DOM, куда будет вставлен canvas.
  • scale.mode — режим масштабирования. Phaser.Scale.FIT подгоняет размеры игры под доступное пространство браузера, сохраняя соотношение сторон.
  • scale.autoCenter — настройка центрирования. Phaser.Scale.CENTER_BOTH выравнивает canvas и по горизонтали, и по вертикали.

Режимы масштабирования

Phaser предоставляет несколько режимов масштабирования через Phaser.Scale:

  1. NONE — Canvas остаётся фиксированного размера, без масштабирования.
  2. FIT — масштабирует игру так, чтобы она полностью помещалась в окно, сохраняя пропорции.
  3. ENVELOP — растягивает игру на всё окно, может обрезать части сцены.
  4. RESIZE — Canvas динамически подстраивается под размер окна браузера, меняя внутренние размеры игры.

Выбор режима зависит от требований к адаптивности. Для центрации чаще всего используется FIT, чтобы игра оставалась полностью видимой и при этом располагалась по центру.


Автоцентрирование в DOM

Фокус на autoCenter позволяет Phaser автоматически размещать canvas внутри родительского элемента:

  • Phaser.Scale.CENTER_HORIZONTALLY — центрирование по горизонтали.
  • Phaser.Scale.CENTER_VERTICALLY — центрирование по вертикали.
  • Phaser.Scale.CENTER_BOTH — центрирование по обеим осям.

При использовании CENTER_BOTH и режима FIT игра будет масштабироваться и располагаться строго по центру, независимо от размеров окна браузера.


Пример адаптивного контейнера

HTML-разметка:

<body>
    <div id="game-container" style="width: 100%; height: 100%; margin: 0; padding: 0;"></div>
</body>

CSS:

html, body {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background-color: #000;
}

Phaser автоматически вставит canvas внутрь #game-container и центрирует его, если включена опция autoCenter.


Динамическая подстройка при изменении окна

Даже при корректной конфигурации важно отслеживать изменение размера окна:

window.addEventListener('resize', () => {
    game.scale.resize(window.innerWidth, window.innerHeight);
});

game.scale.resize() пересчитывает размеры canvas и центрирует его заново, особенно важно при режиме RESIZE или FIT.


Практические рекомендации

  • Сохранять соотношение сторон — это предотвращает искажения графики на экранах с нестандартными пропорциями.
  • Использовать контейнер с 100% шириной и высотой — Canvas корректно подстраивается под весь доступный экран.
  • Обновлять размеры при ресайзе — поддерживает адаптивность при смене ориентации или изменении размеров окна.
  • Проверять разные устройства — особенно мобильные браузеры, где масштабирование и центрирование ведут себя иначе.

Управление позиционированием вручную

Если стандартного автоцентрирования недостаточно, можно управлять canvas вручную через CSS и JS:

const canvas = game.canvas;
canvas.style.position = 'absolute';
canvas.style.left = `${(window.innerWidth - canvas.width) / 2}px`;
canvas.style.top = `${(window.innerHeight - canvas.height) / 2}px`;

Такой подход позволяет реализовать сложные схемы центрирования, например, при фиксированных размерах игры или нестандартных пропорциях.


Поддержка HiDPI и Retina

Для устройств с высокой плотностью пикселей стоит использовать:

const config = {
    ...,
    scale: {
        mode: Phaser.Scale.FIT,
        autoCenter: Phaser.Scale.CENTER_BOTH,
        resolution: window.devicePixelRatio
    }
};

resolution увеличивает плотность отрисовки, что делает графику четкой на Retina и подобных дисплеях. Центрирование при этом не нарушается.