О чем этот пример

При создании интерфейсов или игровых элементов часто нужно ограничить их размер, чтобы они не выходили за допустимые границы. Класс `Phaser.Structs.Size` предоставляет удобный способ работы с шириной, высотой и соотношением сторон, а метод `setMax()` позволяет задать жесткий верхний предел. Эта статья покажет, как динамически менять размер объекта с учетом ограничений, что полезно для создания резиновых контейнеров, UI-панелей или камеры с максимальным зумом.

Версия 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, Phaser.Structs.Size.NONE);

        child.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 — это вспомогательный класс для управления парой значений: шириной и высотой. Он автоматически вычисляет и хранит их соотношение сторон (aspectRatio). Это особенно удобно, когда нужно изменять размеры, сохраняя пропорции, или накладывать на них ограничения.

В примере создается экземпляр child с начальными размерами 420x340. Флаг Phaser.Structs.Size.NONE указывает, что при изменении размеров не нужно сохранять соотношение сторон — ширина и высота могут меняться независимо.

const child = new Phaser.Structs.Size(420, 340, Phaser.Structs.Size.NONE);

Установка максимальных границ с помощью setMax()

Метод setMax() задает максимально допустимые значения для ширины и высоты объекта Size. Если новые размеры, установленные через setSize(), превысят эти лимиты, они будут автоматически уменьшены до указанного максимума.

В коде мы ограничиваем child значениями 640x480. Это значит, что ни ширина, ни высота не смогут стать больше этих чисел, даже если пользователь переместит курсор за эти границы.

child.setMax(640, 480);

Динамическое изменение размеров по движению курсора

В примере размеры объекта привязаны к положению курсора мыши. При каждом движении (pointermove) вызывается child.setSize(pointer.x, pointer.y), который пытается установить новые размеры равными координатам курсора. Однако, если pointer.x или pointer.y превысят 640 или 480 соответственно, setSize() учтет ограничение от setMax() и установит значение на максимуме.

Затем вызывается функция draw(), которая очищает холст, рисует прямоугольник с текущими размерами child и обновляет текстовую панель с актуальными числами.

this.input.on('pointermove', pointer => {
    child.setSize(pointer.x, pointer.y);
    draw();
});

Функция отрисовки использует debug — графический объект для визуализации, и text — текстовый объект для вывода данных.

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}`
    ]);
};

Практическое применение и настройка

Такой подход полезен для создания элементов интерфейса, которые должны реагировать на изменения окна, но не превышать заданных размеров. Вы можете легко адаптировать пример: - Замените Phaser.Structs.Size.NONE на Phaser.Structs.Size.WIDTH_CONTROLS_HEIGHT или Phaser.Structs.Size.HEIGHT_CONTROLS_WIDTH, чтобы изменение одной величины автоматически меняло другую с сохранением соотношения сторон. - Используйте setMin() для установки минимальных размеров вместе с setMax(), создав полный диапазон. - Применяйте Size для управления размером игрового контейнера, камеры или области отрисовки спрайтов.

Конфигурация игры стандартна: создается экземпляр Phaser.Game с указанием сцены Example и базовыми размерами холста 800x600.

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: Example
};
const game = new Phaser.Game(config);

Что попробовать дальше

Использование Phaser.Structs.Size с методом setMax() дает простой и мощный контроль над размерами объектов в вашей игре. Вы можете экспериментировать: добавьте обработчик клика для сброса размеров, комбинируйте минимальные и максимальные ограничения или привяжите размеры к данным из конфигурационного файла. Это отличная основа для создания адаптивных UI-компонентов в Phaser.