О чем этот пример
Создание игр, которые одинаково хорошо выглядят на экранах разных размеров — частая задача для разработчиков. Особенно критично это для пиксель-арта, где неаккуратное масштабирование может "смазать" чёткие пиксельные границы и испортить визуальный стиль. Пример 'fit and snap' демонстрирует, как использовать менеджер масштабирования Phaser, чтобы игра автоматически подстраивалась под размер окна браузера, сохраняя целостность ваших пиксельных ассетов.
Версия 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/dr-ick.png');
}
create ()
{
this.add.image(0, 0, 'pic').setOrigin(0);
}
}
const config = {
type: Phaser.AUTO,
backgroundColor: '#2dab2d',
pixelArt: true,
scale: {
mode: Phaser.Scale.FIT,
parent: 'phaser-example',
autoCenter: Phaser.Scale.CENTER_BOTH,
width: 240,
height: 160,
min: {
width: 240,
height: 160
},
snap: {
width: 240,
height: 160
}
},
scene: Example
};
const game = new Phaser.Game(config);
Зачем нужен Scale Manager?
Раньше разработчикам приходилось вручную рассчитывать масштаб холста и позиционирование элементов при изменении размеров окна. Phaser Scale Manager берёт эту рутину на себя. Он автоматически управляет элементом <canvas>, его CSS-свойствами и внутренней системой координат игры. Это позволяет вам, как разработчику, работать в фиксированной системе координат (например, 240x160), не беспокоясь о реальном разрешении экрана пользователя.
В примере ключевая цель — отобразить изображение, загруженное как 'pic', так, чтобы оно всегда было видно целиком, сохраняло свои пропорции и чёткость пикселей.
Конфигурация scale: FIT, CENTER_BOTH и min
Сердце примера — объект конфигурации scale в основном конфиге игры. Разберём его ключевые свойства.
scale: {
mode: Phaser.Scale.FIT,
parent: 'phaser-example',
autoCenter: Phaser.Scale.CENTER_BOTH,
width: 240,
height: 160,
min: {
width: 240,
height: 160
}
}
* mode: Phaser.Scale.FIT — это основной режим масштабирования. Он гарантирует, что игровая область (240x160) будет пропорционально увеличена или уменьшена, чтобы целиком поместиться в отведённый ей родительский контейнер, без обрезки. По бокам или сверху/снизу могут появиться чёрные полосы (или полосы фона игры).
* autoCenter: Phaser.Scale.CENTER_BOTH — автоматически выравнивает отмасштабированную игровую область по центру родительского контейнера и по горизонтали, и по вертикали.
* width и height (240, 160) — это внутреннее, «игровое» разрешение. В этой системе координат размещаются все ваши игровые объекты.
* Объект min устанавливает минимальный размер, до которого может быть уменьшена игровая область. Это страховка от того, что игра станет слишком маленькой.
Магия свойства snap для пиксель-арта
Свойство snap — это секретный ингредиент для сохранения чёткости пиксель-арта. Оно работает в паре с mode: Phaser.Scale.FIT.
snap: {
width: 240,
height: 160
}
Без snap Phaser.FIT может масштабировать холст до нецелых значений (например, в 1.78 раза). При отрисовке пиксельной графики на таком холсте браузер будет применять сглаживание (anti-aliasing), что сделает края размытыми.
Свойство snap заставляет менеджер масштабирования подбирать такой коэффициент увеличения, чтобы итоговый размер холста в пикселях был кратен базовому разрешению (240x160). Например, вместо множителя 1.78 будет выбран 2. Это гарантирует, что каждый виртуальный пиксель игры будет отрисован ровно 2x2, 3x3 и т.д. реальными пикселями экрана, сохраняя идеальную чёткость.
Важно: для работы snap также необходимо установить pixelArt: true в основном конфиге игры. Этот флаг отключает встроенное в браузер сглаживание изображений (imageSmoothing).
Размещение объектов в фиксированной системе координат
Благодаря настройкам scale, вся логика позиционирования в коде сцены работает в простой, предсказуемой системе координат 240x160. В методе create мы размещаем изображение в точке (0, 0).
create ()
{
this.add.image(0, 0, 'pic').setOrigin(0);
}
* this.add.image(0, 0, 'pic') — создаёт объект изображения в левом верхнем углу игрового мира.
* .setOrigin(0) — устанавливает точку привязки (origin) изображения в его левый верхний угол (0,0). Это значит, что координаты (0,0) объекта совпадут с левым верхним углом его текстуры. В сочетании с координатами (0,0) сцены это гарантирует, что изображение будет плотно прижато к краю игровой области.
Вы можете размещать другие объекты, используя эти же координаты (от 0 до 240 по X и от 0 до 160 по Y), и Scale Manager позаботится об их правильном отображении на любом экране.
Что попробовать дальше
Настройка scale с режимом FIT, центрированием CENTER_BOTH и свойством snap — это мощный и элегантный способ создать адаптивный интерфейс для пиксель-арт игры, который сохраняет чёткость графики. Для экспериментов попробуйте:
1. Изменить базовые width и height на другие значения и посмотреть, как меняется масштабирование.
2. Убрать свойство snap и сравнить чёткость изображения при изменении размера окна.
3. Заменить Phaser.Scale.FIT на Phaser.Scale.ENVELOP (изображение заполнит весь контейнер, возможна обрезка) и оценить разницу в поведении.
