О чем этот пример
При создании интерфейсов или адаптивных игровых элементов часто нужно ограничить изменение размеров объектов. Например, чтобы кнопка не становилась слишком маленькой или чтобы игровая область сохраняла читаемость. Встроенный в Phaser класс `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 parent = new Phaser.Structs.Size(640, 480);
const child = new Phaser.Structs.Size(420, 340, Phaser.Structs.Size.NONE, parent);
child.setMin(320, 240);
const draw = () =>
{
debug.clear().translateCanvas(10, 10);
debug.lineStyle(1.5, 0xffff00).strokeRect(1, 1, parent.width, parent.height);
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.NONE. Это означает, что изначально не применяются никакие автоматические режимы подгонки (вроде FIT или ENVELOP), и мы будем управлять размером вручную.
const parent = new Phaser.Structs.Size(640, 480);
const child = new Phaser.Structs.Size(420, 340, Phaser.Structs.Size.NONE, parent);
Установка минимального предела
Ключевой метод в этом примере — setMin(). Он устанавливает минимально допустимые значения ширины и высоты для дочернего размера. После вызова этого метода любые попытки задать размер меньше указанного предела будут автоматически скорректированы. В нашем случае минимальный размер установлен в 320x240 пикселей.
child.setMin(320, 240);
Динамическое изменение и визуализация
Основная логика взаимодействия связана с обработкой движения указателя мыши. При каждом движении курсора размер дочернего объекта обновляется методом setSize(), куда передаются текущие координаты указателя. Затем вызывается функция draw(), которая очищает старое изображение и отрисовывает обновленные прямоугольники.
this.input.on('pointermove', pointer => {
child.setSize(pointer.x, pointer.y);
draw();
});
Функция draw() выполняет три действия:
1. Очищает графический объект debug и сдвигает начало координат для удобства отрисовки.
2. Рисует контур родительского прямоугольника и залитый дочерний прямоугольник с полупрозрачным зеленым цветом.
3. Обновляет текстовое поле актуальными значениями ширины, высоты и соотношения сторон дочернего размера.
const draw = () => {
debug.clear().translateCanvas(10, 10);
debug.lineStyle(1.5, 0xffff00).strokeRect(1, 1, parent.width, parent.height);
debug.fillStyle(0x00ff00, 0.5).fillRect(1, 1, child.width, child.height);
text.setText([
`width: ${child.width}`,
`height: ${child.height}`,
`aspect ratio: ${child.aspectRatio}`
]);
};
Конфигурация игры и запуск
Сцена включается в конфигурацию игры стандартным образом. Важно отметить, что размер холста игры (800x600) не связан напрямую с логическими размерами наших прямоугольников — они отрисовываются внутри сцены со смещением.
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Класс Phaser.Structs.Size — это мощный инструмент для управления размерами объектов с поддержкой ограничений и привязок. Показанный пример демонстрирует, как легко задать минимальный предел и реагировать на пользовательский ввод.
Для экспериментов попробуйте:
1. Добавить максимальный размер с помощью метода setMax().
2. Использовать другие флаги инициализации, например Phaser.Structs.Size.FIT, чтобы увидеть автоматическую подгонку.
3. Применить этот механизм к реальным игровым объектам, например, для ограничения масштабирования спрайта.
