О чем этот пример
При разработке игр под разные устройства важно правильно управлять отображением игрового холста. Phaser предоставляет мощную систему масштабирования через объект `Scale Manager`. В этой статье мы разберем режим `ENVELOP` и настройку минимальных (`min`) и максимальных (`max`) размеров холста. Это позволит вашей игре сохранять пропорции и качество изображения на экранах с самым разным разрешением, от мобильных устройств до больших мониторов, без растягивания или обрезания критически важных областей.
Версия 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: {
mode: Phaser.Scale.ENVELOP,
parent: 'phaser-example',
width: 800,
height: 600,
min: {
width: 800,
height: 600
},
max: {
width: 1600,
height: 1200
}
},
scene: Example
};
const game = new Phaser.Game(config);
Что такое режим ENVELOP?
Режим Phaser.Scale.ENVELOP — это один из способов масштабирования игрового холста. Его логика проста: холст будет масштабироваться так, чтобы полностью поместиться в область своего родительского контейнера (например, <div> на странице), при этом сохраняя исходные пропорции (aspect ratio).
Ключевое отличие от других режимов, например FIT, в том, что ENVELOP гарантирует, что холст *полностью покроет* доступную область. Это может привести к тому, что часть игрового мира окажется за пределами видимой области, если пропорции области и игры не совпадают. Поэтому данный режим часто используют в связке с ограничениями по минимальному и максимальному размеру, чтобы контролировать этот процесс.
Настройка конфигурации Scale
Основная настройка происходит в объекте config при создании игры. Внутри свойства scale мы определяем режим, целевой DOM-элемент и ключевые размеры.
const config = {
type: Phaser.AUTO,
backgroundColor: '#2dab2d',
scale: {
mode: Phaser.Scale.ENVELOP,
parent: 'phaser-example',
width: 800,
height: 600,
min: {
width: 800,
height: 600
},
max: {
width: 1600,
height: 1200
}
},
scene: Example
};
* mode: Устанавливает режим масштабирования. В нашем случае — Phaser.Scale.ENVELOP.
* parent: ID DOM-элемента, внутрь которого будет помещен игровой холст.
* width и height: Это *базовое* или *номинальное* разрешение вашей игры (800x600). На этом разрешении игра отрисовывается «как есть», 1 пиксель игры равен 1 пикселю на холсте.
* min и max: Эти объекты задают жесткие границы, за которые не сможет выйти масштабированный холст. Они определены в пикселях.
Как работают min и max?
Свойства min и max устанавливают абсолютные границы для физического размера игрового холста в пикселях.
* **Минимальный размер (min)**: Если расчетный размер холста по логике режима ENVELOP окажется меньше указанных здесь значений (например, на очень маленьком экране), холст будет принудительно увеличен до размеров min.width и min.height. В нашем примере игра никогда не будет отображаться в области меньше 800x600 пикселей. Это защищает игровое пространство от сильного сжатия, при котором контент станет нечитаемым.
* **Максимальный размер (max)**: Если расчетный размер по логике ENVELOP окажется больше указанных здесь значений (например, на огромном 4K-мониторе), холст будет принудительно ограничен размерами max.width и max.height. В примере игра не займет область больше 1600x1200 пикселей. Это предотвращает чрезмерное растягивание пиксель-арта или растровых изображений, сохраняя качество графики.
Таким образом, игра будет масштабироваться в диапазоне от 800x600 до 1600x1200, следуя правилу ENVELOP, но не выходя за эти рамки.
Рекомендации по использованию в сцене
При использовании ENVELOP с min/max важно правильно располагать объекты в сцене, особенно фон. В предоставленном примере фоновая картинка позиционируется в точке (0, 0) с установленным setOrigin(0).
create ()
{
this.add.image(0, 0, 'pic').setOrigin(0);
}
Метод setOrigin(0) устанавливает точку привязки (origin) изображения в его левый верхний угол. Это гарантирует, что при любом масштабировании и возможной обрезке (так как ENVELOP может скрывать часть контента) изображение будет всегда начинаться от левого верхнего угла игрового мира. Если бы точка привязки была по умолчанию в центре (0.5), при обрезке можно было бы увидеть черные или фоновые края по углам. Для фоновых или заполняющих весь мир изображений такая привязка к углу — стандартная практика.
Что попробовать дальше
Использование связки Phaser.Scale.ENVELOP с параметрами min и max дает надежный контроль над отображением игры на различных экранах. Вы защищаете минимальную читаемость интерфейса и предотвращаете максимальное ухудшение качества графики. Для экспериментов попробуйте:
1. Изменить значения min и max, чтобы увидеть, как игра ведет себя на экранах разного размера.
2. Заменить режим на Phaser.Scale.FIT и сравнить поведение — FIT гарантирует, что вся игра будет видна, но может появиться пустое пространство (поля) вокруг.
3. Добавить в сцену элементы интерфейса (HUD) и использовать для них отдельную камеру или систему позиционирования относительно краев экрана, чтобы они оставались доступными при обрезке игрового мира.
