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

В игровой разработке часто требуется управлять пропорциями объектов. Знание соотношения сторон (aspect ratio) прямоугольника может быть ключевым для динамического изменения размеров UI-элементов, камеры или игровых спрайтов, сохраняя их исходные пропорции. В этой статье мы разберем, как использовать встроенный метод Phaser для получения этого значения и как применить его на практике для создания интерактивных элементов.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x0000aa } });

        const rect = new Phaser.Geom.Rectangle(350, 250, 100, 100);

        const text = this.add.text(100, 100, '');

        this.input.on('pointermove', pointer =>
        {

            rect.width = Phaser.Math.FloorTo((pointer.x - 400) * 2, 1, 25);
            rect.height = Phaser.Math.FloorTo((pointer.y - 300) * 2, 1, 25);

            Phaser.Geom.Rectangle.CenterOn(rect, 400, 300);

            text.setText(`Aspect Ratio: ${Phaser.Geom.Rectangle.GetAspectRatio(rect)}`);

            redraw();

        });

        redraw();

        function redraw ()
        {
            graphics.clear();

            graphics.strokeRectShape(rect);
        }
    }
}

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

const game = new Phaser.Game(config);

Что такое соотношение сторон и зачем оно нужно

Соотношение сторон прямоугольника — это отношение его ширины к высоте. Это фундаментальное понятие используется повсеместно: от настройки отзывчивого интерфейса до корректного отображения текстур и работы камеры.

В Phaser для объекта типа Phaser.Geom.Rectangle существует удобный статический метод GetAspectRatio(), который мгновенно вычисляет это значение. Его использование избавляет от необходимости писать собственные вычисления вроде width / height и обеспечивает единообразие кода.

const ratio = Phaser.Geom.Rectangle.GetAspectRatio(myRect);

Разбор примера: интерактивный прямоугольник

Рассмотрим пример, где соотношение сторон вычисляется в реальном времени при движении курсора. Создается сцена, графический объект graphics для отрисовки, прямоугольник rect и текстовое поле text для вывода результата.

class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x0000aa } });
        const rect = new Phaser.Geom.Rectangle(350, 250, 100, 100);
        const text = this.add.text(100, 100, '');

Обработка ввода и динамический пересчет

Ключевая логика заключена в обработчике события 'pointermove'. При движении мыши ширина и высота прямоугольника изменяются в зависимости от позиции курсора. Для избегания нулевых или отрицательных размеров используется утилита Phaser.Math.FloorTo, которая округляет значение в меньшую сторону с заданным шагом и минимальным пределом.

Затем, чтобы прямоугольник оставался центрированным, применяется метод Phaser.Geom.Rectangle.CenterOn().

this.input.on('pointermove', pointer =>
{
    rect.width = Phaser.Math.FloorTo((pointer.x - 400) * 2, 1, 25);
    rect.height = Phaser.Math.FloorTo((pointer.y - 300) * 2, 1, 25);
    Phaser.Geom.Rectangle.CenterOn(rect, 400, 300);

Получение соотношения сторон и перерисовка

После обновления размеров прямоугольника вызывается метод Phaser.Geom.Rectangle.GetAspectRatio(rect). Полученное значение передается в текстовое поле для отображения пользователю. Функция redraw() очищает холст graphics и заново рисует текущую форму прямоугольника.

text.setText(`Aspect Ratio: ${Phaser.Geom.Rectangle.GetAspectRatio(rect)}`);
    redraw();
});

function redraw ()
{
    graphics.clear();
    graphics.strokeRectShape(rect);
}

Важно помнить, что GetAspectRatio возвращает простое число (width / height). Значение больше 1 означает, что ширина больше высоты, и наоборот.

Конфигурация и запуск игры

Пример завершается стандартной для Phaser конфигурацией игры, которая задает размеры холста, тип рендерера и указывает класс сцены для запуска.

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

const game = new Phaser.Game(config);

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

Метод Phaser.Geom.Rectangle.GetAspectRatio — это небольшой, но мощный инструмент для работы с геометрией. Он идеально подходит для задач, где необходимо сохранять или проверять пропорции объектов. Для экспериментов попробуйте

  1. ограничить изменение прямоугольника, чтобы его соотношение сторон оставалось в заданных пределах (например, для имитации экранов 4:3 или 16:9)
  2. использовать полученное значение для масштабирования спрайта, привязав его к размеру прямоугольника
  3. создать систему динамической подстройки размера игрового поля под разные устройства, опираясь на соотношение сторон экрана