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

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

Версия 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(400, 300);
        const child = new Phaser.Structs.Size(100, 100, Phaser.Structs.Size.NONE, parent);

        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?

Phaser.Structs.Size — это вспомогательный класс для работы с размерами объектов. Он позволяет задавать ширину, высоту, соотношение сторон (aspect ratio) и связывать размеры родительского и дочернего объектов. Это особенно удобно при создании адаптивных интерфейсов или элементов игры, которые должны реагировать на изменения экрана.

Класс поддерживает несколько режимов масштабирования через константы: NONE, WIDTH_CONTROLS_HEIGHT, HEIGHT_CONTROLS_WIDTH, FIT и ENVELOP. В этом примере мы фокусируемся на режиме NONE.

const parent = new Phaser.Structs.Size(400, 300);
const child = new Phaser.Structs.Size(100, 100, Phaser.Structs.Size.NONE, parent);

Режим NONE: независимое изменение размеров

Режим NONE означает, что размер дочернего объекта не привязан к родительскому через автоматическое масштабирование. Вы можете менять ширину и высоту дочернего объекта независимо, используя метод setSize(). Однако объекты остаются связанными — если изменится размер родителя, дочерний объект может обновить свои свойства (например, положение), но его ширина и высота не изменятся автоматически.

В примере размер дочернего объекта задается движением указателя мыши (pointer.x и pointer.y). Это демонстрирует интерактивное управление размерами.

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

Визуализация и отладка

Для наглядности в коде создаются графические объекты: желтый прямоугольник отображает родительский размер, зеленый — дочерний. Также выводится текстовая информация с текущими значениями ширины, высоты и соотношения сторон.

Функция draw() очищает графику, обновляет позиции и рисует оба прямоугольника. Она вызывается при инициализации и каждом движении мыши.

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

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

Режим NONE полезен в сценариях, где размер элемента должен меняться вручную, но требуется сохранить связь с родителем для других вычислений. Например: - Кастомизация окон интерфейса (игрок может растягивать панели). - Создание редакторов уровней с изменяемыми размерами блоков. - Динамические элементы HUD, которые обновляются в зависимости от действий игрока.

Соотношение сторон (aspectRatio) вычисляется автоматически при изменении размеров и может использоваться для проверок или дополнительной логики.

// Соотношение сторон доступно через свойство aspectRatio
console.log(child.aspectRatio); // width / height

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

Режим NONE в Phaser.Structs.Size предоставляет гибкость для ручного управления размерами объектов с сохранением связи между родительскими и дочерними элементами. Это отличный выбор для интерактивных или кастомизируемых компонентов игры. Для экспериментов попробуйте: 1. Изменить режим на FIT или ENVELOP и посмотреть, как поведение меняется автоматически. 2. Добавить ограничения на минимальный и максимальный размер дочернего объекта. 3. Использовать размеры для позиционирования других игровых объектов относительно родительского контейнера.