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

Работа с геометрией — основа для множества игровых механик: от патрулирования врагов до движения камеры. В этом примере мы разберем, как использовать метод `getPoint` класса `Phaser.Geom.Rectangle`, чтобы плавно перемещать объект вдоль границ прямоугольной области. Этот подход позволяет легко задавать сложные траектории, не прибегая к сложной математике вручную.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    a = 0;
    point;
    rect;
    graphics;

    create ()
    {
        this.graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x00ff00 }, fillStyle: { color: 0xff0000 }});

        this.rect = new Phaser.Geom.Rectangle(100, 100, 300, 180);
        this.point = new Phaser.Geom.Rectangle(0, 0, 16, 16);
    }

    update ()
    {
        this.a += 0.005;

        if (this.a > 1)
        {
            this.a = 0;
        }

        this.rect.getPoint(this.a, this.point);

        this.graphics.clear();
        this.graphics.lineStyle(2, 0x00ff00);
        this.graphics.strokeRectShape(this.rect);

        this.graphics.fillStyle(0xff00ff);
        this.graphics.fillRect(this.point.x - 8, this.point.y - 8, this.point.width, this.point.height);
    }
}

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

const game = new Phaser.Game(config);

Суть метода getPoint

Метод Phaser.Geom.Rectangle.getPoint(position, output) — это удобный инструмент для получения точки на периметре прямоугольника. Вместо того чтобы вручную вычислять координаты на каждой стороне, вы просто передаете нормализованное значение от 0 до 1, где 0 соответствует начальной точке прямоугольника, а 1 — возврату в ту же точку после полного обхода.

Первый аргумент, position, определяет позицию на периметре. Второй, output, — это объект (например, точка или прямоугольник), в который будут записаны вычисленные координаты `xиy`. Это позволяет переиспользовать объект, избегая создания новых в каждом кадре, что полезно для оптимизации.

Разбор сцены и инициализации

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

class Example extends Phaser.Scene
{
    a = 0;
    point;
    rect;
    graphics;

    create ()
    {
        this.graphics = this.add.graphics({ lineStyle: { width: 2, color: 0x00ff00 }, fillStyle: { color: 0xff0000 }});
        this.rect = new Phaser.Geom.Rectangle(100, 100, 300, 180);
        this.point = new Phaser.Geom.Rectangle(0, 0, 16, 16);
    }

Здесь this.a — это наша нормализованная позиция (от 0 до 1). Обратите внимание, что this.point создается как прямоугольник. Это нужно, потому что метод getPoint запишет в него только свойства `xиy. Свойстваwidthиheight` мы используем позже для отрисовки.

Анимация в методе update

Вся логика движения происходит в update(). Значение this.a плавно увеличивается, а когда достигает 1, сбрасывается на 0, создавая циклическое движение.

update ()
{
    this.a += 0.005;
    if (this.a > 1)
    {
        this.a = 0;
    }
    this.rect.getPoint(this.a, this.point);

Строка this.rect.getPoint(this.a, this.point); — это сердце примера. Она вычисляет текущую позицию на периметре this.rect и записывает координаты в объект this.point. Далее графика очищается, и происходит перерисовка.

this.graphics.clear();
    this.graphics.lineStyle(2, 0x00ff00);
    this.graphics.strokeRectShape(this.rect);
    this.graphics.fillStyle(0xff00ff);
    this.graphics.fillRect(this.point.x - 8, this.point.y - 8, this.point.width, this.point.height);
}

Зеленым контуром рисуется основной прямоугольник с помощью strokeRectShape. Движущийся объект (малиновый квадрат) рисуется с помощью fillRect. Мы центрируем квадрат на вычисленной точке, вычитая половину его размера из координат.

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

Это стандартная конфигурация игры Phaser, которая указывает размеры окна, тип рендерера и используемую сцену.

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

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

Метод getPoint — это мощный и лаконичный способ задания движения по прямоугольной траектории. Вы можете использовать его для создания патрульных путей NPC, орбит спутников вокруг зоны или анимации интерфейсных элементов. Попробуйте изменить скорость движения, привязать к точке не спрайт, а камеру (this.cameras.main), или использовать несколько прямоугольников для создания сложного маршрута.