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

В игровой разработке часто требуется вычислить расстояние между точками: для проверки достижения цели, расчета дальности атаки или определения силы прыжка. Встроенный модуль геометрии Phaser предоставляет простые и эффективные инструменты для таких операций. В этой статье разберем, как использовать объект `Phaser.Geom.Line` и статический метод `Length()` для динамического расчета расстояния, а также визуализируем результат.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {

        const graphics = this.add.graphics({ lineStyle: { width: 4, color: 0xaa00aa } });

        const line = new Phaser.Geom.Line(400, 300, 550, 300);

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

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

            line.x2 = pointer.x;
            line.y2 = pointer.y;

            redraw();
        });

        redraw();

        function redraw ()
        {
            graphics.clear();

            graphics.strokeLineShape(line);

            const length = Phaser.Geom.Line.Length(line);

            graphics.lineStyle(2, 0x00aa00);
            graphics.strokeCircle(400, 300, length);

            text.setText(`Line Length: ${length}`);
        }
    }
}

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

const game = new Phaser.Game(config);

Создание сцены и базовых объектов

В методе create() сцены мы подготавливаем все необходимые объекты: графический контекст для рисования, линию, текстовое поле для вывода информации и слушатель событий мыши.

const graphics = this.add.graphics({ lineStyle: { width: 4, color: 0xaa00aa } });
const line = new Phaser.Geom.Line(400, 300, 550, 300);
const text = this.add.text(50, 50, '');

Графический объект graphics настроен на рисование линий толщиной 4 пикселя пурпурным цветом. Линия line создается с начальной точкой в центре экрана (400, 300) и конечной, изначально смещенной вправо. Текстовое поле text будет отображать числовую длину.

Обработка движения указателя

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

this.input.on('pointermove', pointer => {
    line.x2 = pointer.x;
    line.y2 = pointer.y;
    redraw();
});

Это создает интерактивность: пользователь видит, как линия тянется за курсором мыши.

Функция перерисовки и вычисление длины

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

function redraw ()
{
    graphics.clear();
    graphics.strokeLineShape(line);
    const length = Phaser.Geom.Line.Length(line);
    graphics.lineStyle(2, 0x00aa00);
    graphics.strokeCircle(400, 300, length);
    text.setText(`Line Length: ${length}`);
}

Ключевая строка — вызов Phaser.Geom.Line.Length(line). Этот статический метод принимает объект линии в качестве аргумента и возвращает ее длину по теореме Пифагора. Для наглядности эта же длина используется как радиус зеленой окружности, нарисованной вокруг начальной точки линии. Текстовое поле обновляется актуальным значением.

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

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

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

Конфигурационный объект config задает размеры холста, рендерер и указывает, какой класс является основной сценой. Экземпляр Phaser.Game запускает игровой цикл с этими настройками.

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

Метод Phaser.Geom.Line.Length() — это надежный и производительный способ расчета расстояния между двумя точками в игровом мире. Полученное значение можно использовать не только для визуализации, но и для геймдейла: например, чтобы урон от выстрела падал с расстоянием или чтобы враг начинал преследование, когда игрок находится в определенном радиусе. Для экспериментов попробуйте зафиксировать длину линии и менять ее угол, создать "линейку" между двумя перемещаемыми спрайтами или использовать длину для расчета скорости перемещения объекта по этой линии.