О чем этот пример
При создании игр часто возникает необходимость динамически менять размеры игровых объектов, но при этом соблюдать определенные границы. Класс `Phaser.Structs.Size` предоставляет простой и мощный инструмент для управления шириной, высотой и соотношением сторон объекта с установленными минимальными и максимальными пределами. Эта статья покажет, как использовать этот класс для создания адаптивных элементов интерфейса или игровых сущностей, размер которых зависит от действий игрока, но всегда остается в заданных рамках.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
const debug = this.add.graphics();
const text = this.add.text(10, 540, '', { fill: '#00ff00' });
const child = new Phaser.Structs.Size(420, 340);
child.setMin(320, 240).setMax(640, 480);
const draw = () =>
{
debug.clear().translateCanvas(10, 10);
debug.fillStyle(0x00ff00, 0.5).fillRect(1, 1, child.width, child.height);
text.setText([
`width: ${child.width}`,
`height: ${child.height}`,
`aspect ratio: ${child.aspectRatio}`
]);
};
this.input.on('pointermove', pointer =>
{
child.setSize(pointer.x, pointer.y);
draw();
});
draw();
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Что такое Phaser.Structs.Size?
Phaser.Structs.Size — это вспомогательный класс в Phaser 3, предназначенный для управления парой значений: шириной и высотой. Его ключевая особенность — возможность установки минимальных (min) и максимальных (max) ограничений. Когда вы пытаетесь задать новые размеры с помощью метода setSize, класс автоматически "прижимает" эти значения к установленным границам.
Это особенно полезно для: * UI-элементов, которые можно перетаскивать, но нельзя сделать слишком маленькими или большими. * Областей игры или камер, которые должны масштабироваться в определенных пределах. * Любого объекта, чьи размеры зависят от внешних факторов (например, положения курсора), но должны оставаться в разумных рамках.
Разбор примера кода: Создание и настройка
В примере создается объект child класса Size и сразу задаются его ограничения.
const child = new Phaser.Structs.Size(420, 340);
child.setMin(320, 240).setMax(640, 480);
Здесь:
1. new Phaser.Structs.Size(420, 340) — создает экземпляр с начальной шириной 420 пикселей и высотой 340 пикселей.
2. .setMin(320, 240) — устанавливает минимально допустимые размеры: ширина не может быть меньше 320, высота — меньше 240.
3. .setMax(640, 480) — устанавливает максимально допустимые размеры: ширина не может превышать 640, высота — 480.
Методы setMin и setMax можно вызывать по цепочке, как показано в коде.
Связь с пользовательским вводом и отрисовка
Основная логика примера — изменение размера объекта child в зависимости от положения курсора мыши и визуализация результата.
Обработчик события движения указателя (pointermove) вызывает метод setSize объекта child, передавая ему координаты курсора.
this.input.on('pointermove', pointer => {
child.setSize(pointer.x, pointer.y);
draw();
});
Метод setSize(pointer.x, pointer.y) пытается установить новые размеры. Однако, если переданные значения выходят за установленные ранее границы (минимум 320x240, максимум 640x480), они будут автоматически скорректированы ("зажаты") внутри этого диапазона.
Функция draw() отвечает за визуализацию:
1. Очищает и перемещает контекст отладочной графики (debug).
2. Рисует полупрозрачный зеленый прямоугольник с текущими размерами child.width и child.height.
3. Обновляет текстовое поле, выводя актуальные значения ширины, высоты и соотношения сторон (aspectRatio).
const draw = () => {
debug.clear().translateCanvas(10, 10);
debug.fillStyle(0x00ff00, 0.5).fillRect(1, 1, child.width, child.height);
text.setText([
`width: ${child.width}`,
`height: ${child.height}`,
`aspect ratio: ${child.aspectRatio}`
]);
};
Практическое применение и полезные свойства
Класс Size предлагает не только базовые методы установки размеров и границ. Вот ключевые свойства, которые можно использовать в своих проектах:
* width / height: Текущие размеры объекта (уже с учетом всех ограничений).
* aspectRatio: Текущее соотношение сторон (width / height). Рассчитывается автоматически.
* minWidth, minHeight, maxWidth, maxHeight: Прямой доступ к установленным ограничениям.
Методы для тонкой настройки:
// Установить минимальный размер только по ширине
child.setMinWidth(400);
// Установить максимальный размер только по высоте
child.setMaxHeight(300);
// Ограничить соотношение сторон (полезно для камеры)
// child.setAspectRatio(16/9);
Используйте эти свойства и методы, чтобы создавать сложные правила изменения размеров для ваших спрайтов, зон взаимодействия или элементов HUD.
Что попробовать дальше
Phaser.Structs.Size — это элегантное решение для управления размерами с ограничениями. Оно избавляет от необходимости писать дополнительные проверки (if (width < minWidth) width = minWidth) и делает код чище и понятнее.
**Идеи для экспериментов:**
1. Свяжите размер объекта не с курсором, а со скоростью движения игрового персонажа — пусть его аура или область влияния растет при разгоне.
2. Используйте setAspectRatio, чтобы создать камеру или UI-контейнер, который меняет размер, но всегда сохраняет заданные пропорции (например, 16:9).
3. Примените Size для создания резинового (растягиваемого) элемента панели управления, который можно регулировать, но в разумных пределах.
