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

Работа с геометрией в играх — это не только для визуальных эффектов. Понимание параметров фигур, таких как эллипс, помогает в расчетах столкновений, создании траекторий движения и плавной анимации. В этой статье разберем, как использовать метод `getMinorRadius()` объекта `Phaser.Geom.Ellipse` для получения его малого (половинного) радиуса и визуализируем результат в реальном времени, реагируя на движение мыши. Этот навык пригодится, когда вам нужно, например, ограничить зону действия объекта овальной формой или рассчитать отскок от криволинейной поверхности.

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

Живой запуск

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

Исходный код


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

        const ellipse = new Phaser.Geom.Ellipse(400, 300, 200, 100);

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

            ellipse.setSize(pointer.x, pointer.y);

            redraw();
        });

        redraw();

        function redraw ()
        {
            graphics.clear();

            graphics.fillEllipseShape(ellipse);

            const minorRadius = ellipse.getMinorRadius();

            graphics.strokeCircle(400, 300, minorRadius);
        }
    }
}

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

const game = new Phaser.Game(config);

Создание сцены и графики

Вся логика примера размещается в методе create() сцены. Первым делом мы создаем графический объект (Graphics), который будет рисовать фигуры. Мы сразу задаем ему стили: красный цвет для контура (lineStyle) и бирюзовый для заливки (fillStyle).

const graphics = this.add.graphics({ fillStyle: { color: 0x00aaaa }, lineStyle: { width: 2, color: 0xaa0000 } });

Затем создаем экземпляр эллипса Phaser.Geom.Ellipse. Первые два аргумента — это координаты центра (x, y), а следующие два — ширина и высота (диаметры) эллипса.

const ellipse = new Phaser.Geom.Ellipse(400, 300, 200, 100);

Динамическое изменение размера

Чтобы сделать пример интерактивным, мы подписываемся на событие перемещения указателя (pointermove). Каждый раз при движении мыши мы обновляем размеры эллипса, устанавливая его ширину и высоту равными текущим координатам указателя, и вызываем функцию перерисовки redraw().

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

Метод setSize(width, height) объекта ellipse изменяет его ширину и высоту, сохраняя центр на прежнем месте. Это позволяет в реальном времени видеть, как меняется форма.

Расчет и визуализация малого радиуса

Ключевой метод, который мы изучаем, — это getMinorRadius(). Он возвращает длину малого (половинного) радиуса эллипса. Для эллипса это половина от меньшей из двух осей (ширины или высоты).

Функция redraw() сначала очищает предыдущие отрисовки с помощью graphics.clear(), затем заливает текущий эллипс. После этого получает малый радиус и рисует окружность (strokeCircle) с центром в той же точке, что и эллипс, и с радиусом, равным вычисленному значению.

function redraw ()
{
    graphics.clear();
    graphics.fillEllipseShape(ellipse);
    const minorRadius = ellipse.getMinorRadius();
    graphics.strokeCircle(400, 300, minorRadius);
}

Таким образом, красная окружность всегда будет вписана в эллипс по его меньшей оси, наглядно демонстрируя результат работы метода.

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

Код завершается стандартной для Phaser 3 конфигурацией игры. Мы указываем размеры холста, тип рендерера (Phaser.AUTO), идентификатор родительского HTML-элемента и класс нашей сцены Example.

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

const game = new Phaser.Game(config);

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

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

Метод getMinorRadius() — это простой, но мощный инструмент для работы с геометрией эллипса в Phaser 3. Он предоставляет точное значение, которое можно использовать в физических расчетах, например, для определения внутренней границы овальной зоны. Для экспериментов попробуйте использовать getMajorRadius() (больший радиус) и нарисовать вторую окружность. Или примените полученный радиус в условии столкновения (this.physics.overlap) для объекта, который должен оставаться внутри эллипса. Это отличная база для создания игровых механик с нестандартными формами областей.