Обработка изменения размера окна

В современных веб-играх динамическое изменение размеров экрана является критически важным для корректного отображения на разных устройствах. Библиотека Phaser предоставляет гибкие средства для обработки таких событий и адаптации игрового контента под новые размеры.


Основные подходы к масштабированию

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

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

Пример конфигурации Scale Manager:

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

const game = new Phaser.Game(config);

Ключевой момент: использование autoCenter: Phaser.Scale.CENTER_BOTH гарантирует, что игра всегда будет центрирована в окне.


События изменения размера

Phaser предоставляет событие resize через Scale Manager, позволяющее реагировать на динамическое изменение окна:

this.scale.on('resize', (gameSize, baseSize, displaySize, previousWidth, previousHeight) => {
    const width = gameSize.width;
    const height = gameSize.height;

    // Пример: перерасположение игрового объекта
    player.setPosition(width / 2, height / 2);

    // Обновление камер
    this.cameras.main.setViewport(0, 0, width, height);
});

Параметры события resize:

  • gameSize – новые размеры игрового канваса.
  • baseSize – базовые размеры, заданные в конфиге.
  • displaySize – размеры окна браузера.
  • previousWidth, previousHeight – предыдущие размеры канваса.

Масштабирование игровых объектов

Для корректного отображения объектов при изменении размеров рекомендуется использовать относительные позиции и размеры:

player.x = this.scale.width * 0.5;
player.y = this.scale.height * 0.8;

Использование коэффициентов позволяет сохранить правильное расположение элементов при любом размере окна.

Для спрайтов и текстов можно применять масштабирование через setScale:

player.setScale(this.scale.width / 800, this.scale.height / 600);
scoreText.setStyle({ fontSize: `${24 * this.scale.width / 800}px` });

Адаптация камер

Камеры Phaser не масштабируются автоматически с изменением окна. Необходимо обновлять viewport:

this.cameras.main.setViewport(0, 0, this.scale.width, this.scale.height);

Для более сложных сцен с параллакс-эффектами и слоями можно комбинировать масштабирование камер и позиционирование объектов.


Рекомендации по проектированию адаптивного интерфейса

  1. Использовать контейнеры – Phaser.Container позволяет группировать объекты и масштабировать их одновременно.
  2. Проектировать UI относительно канваса – элементы интерфейса лучше привязывать к краям или центру через координаты, зависящие от this.scale.width и this.scale.height.
  3. Избегать фиксированных размеров – вместо жестких пикселей использовать коэффициенты от базового разрешения.
  4. Обрабатывать событие resize глобально – это позволяет централизованно обновлять позиции, размеры и камеры всех объектов сцены.

Пример комплексной обработки изменения размера

function resizeGame(scene) {
    scene.scale.on('resize', (gameSize) => {
        const width = gameSize.width;
        const height = gameSize.height;

        // Центрирование игрока
        player.setPosition(width / 2, height / 2);

        // Масштабирование UI
        scoreText.setStyle({ fontSize: `${24 * width / 800}px` });
        scoreText.setPosition(width - 150, 50);

        // Масштабирование контейнера
        uiContainer.setScale(width / 800, height / 600);

        // Обновление камеры
        scene.cameras.main.setViewport(0, 0, width, height);
    });
}

Этот подход обеспечивает корректную адаптацию всех ключевых элементов игры под любые изменения размера окна, сохраняя пропорции и расположение объектов.