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

В играх постоянно требуется проверять столкновения объектов. Phaser предлагает мощный, но простой геометрический модуль для таких задач. Этот пример наглядно показывает, как в реальном времени определять пересечение движущейся линии и прямоугольника — основа для создания лучей, мечей, лазеров или проверки видимости. Вы научитесь работать с геометрическими объектами и использовать встроенные методы для коллизий, что гораздо эффективнее «ручных» расчетов.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    graphics;
    rect;
    line;

    create ()
    {
        this.graphics = this.add.graphics();

        this.line = new Phaser.Geom.Line(260, 200, 550, 400);
        this.rect = new Phaser.Geom.Rectangle(32, 32, 128, 96);

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

            Phaser.Geom.Rectangle.CenterOn(this.rect, pointer.x, pointer.y);

        });
    }

    update ()
    {
        Phaser.Geom.Line.Rotate(this.line, 0.01);

        this.graphics.clear();

        this.graphics.lineStyle(2, 0x00ff00);
        this.graphics.strokeLineShape(this.line);

        if (Phaser.Geom.Intersects.LineToRectangle(this.line, this.rect))
        {
            this.graphics.lineStyle(2, 0xff0000);
        }
        else
        {
            this.graphics.lineStyle(2, 0xffff00);
        }

        this.graphics.strokeRectShape(this.rect, 2);
    }
}

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

const game = new Phaser.Game(config);

Инициализация геометрических объектов

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

this.graphics = this.add.graphics();
this.line = new Phaser.Geom.Line(260, 200, 550, 400);
this.rect = new Phaser.Geom.Rectangle(32, 32, 128, 96);

Управление прямоугольником с помощью мыши

Чтобы сделать пример интерактивным, прямоугольник привязан к движению указателя мыши. При каждом движении мыши вызывается статический метод Phaser.Geom.Rectangle.CenterOn. Он перемещает центр прямоугольника в указанные координаты (x, y), что удобнее ручного пересчета позиции.

this.input.on('pointermove', pointer => {
    Phaser.Geom.Rectangle.CenterOn(this.rect, pointer.x, pointer.y);
});

Анимация линии и проверка пересечения

В методе update линия плавно вращается вокруг своего начала с помощью Phaser.Geom.Line.Rotate. Это создает постоянное движение для наглядной демонстрации.

Phaser.Geom.Line.Rotate(this.line, 0.01);

Перед каждой отрисовкой графический буфер очищается, чтобы удалить кадры предыдущего кадра. Затем линия всегда рисуется зеленым цветом.

this.graphics.clear();
this.graphics.lineStyle(2, 0x00ff00);
this.graphics.strokeLineShape(this.line);

Визуализация результата пересечения

Сердце примера — вызов Phaser.Geom.Intersects.LineToRectangle. Этот метод возвращает true или false в зависимости от того, пересекает ли линия прямоугольник. На основе этого результата меняется цвет обводки прямоугольника: красный при пересечении, желтый — при его отсутствии.

if (Phaser.Geom.Intersects.LineToRectangle(this.line, this.rect))
{
    this.graphics.lineStyle(2, 0xff0000);
}
else
{
    this.graphics.lineStyle(2, 0xffff00);
}
this.graphics.strokeRectShape(this.rect);

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

Использование встроенных геометрических методов Phaser, таких как LineToRectangle, делает код чистым и производительным. Для экспериментов попробуйте заменить линию на луч (Phaser.Geom.Line.SetToAngle) для имитации фонарика, добавить несколько прямоугольников-препятствий или использовать результат пересечения для нанесения урона игровому объекту.