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

Плавная анимация движения объектов часто требует не просто линейного перемещения, а вращения вокруг определённой точки. Этот приём используется для создания вращающихся платформ, лопастей вентиляторов или орбитального движения спутников. В статье разбираем, как с помощью встроенного API Phaser.Geom.Triangle реализовать такое вращение, управляя его скоростью и центром.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    t = 0;
    rotateY = 250;
    rotateX = 350;
    triangle;
    graphics;

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

        this.triangle = new Phaser.Geom.Triangle.BuildRight(200, 360, 200, 200);
    }

    update ()
    {
        this.graphics.clear();

        this.t += 0.01;

        Phaser.Geom.Triangle.RotateAroundXY(this.triangle, this.rotateX, this.rotateY, Math.sin(this.t) * 0.05);

        this.graphics.strokeTriangleShape(this.triangle);

        this.graphics.fillPoint(this.rotateX, this.rotateY, 4);
    }
}

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

const game = new Phaser.Game(config);

Подготовка сцены и создание фигуры

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

this.graphics = this.add.graphics({ lineStyle: { width: 2, color: 0xaaaa00 }, fillStyle: { color: 0x0000aa } });

Здесь создаётся объект Graphics с настройками: жёлтая линия толщиной 2 пикселя для контура и синяя заливка для внутренних точек.

this.triangle = new Phaser.Geom.Triangle.BuildRight(200, 360, 200, 200);

С помощью статического метода Phaser.Geom.Triangle.BuildRight() создаётся прямоугольный треугольник. Первые два аргумента (200, 360) — координаты прямого угла. Третий аргумент (200) — ширина (расстояние по X до острого угла), четвёртый (200) — высота (расстояние по Y до другого острого угла).

Анимация и принцип вращения

Основная логика анимации находится в методе update(), который вызывается на каждом кадре.

this.graphics.clear();

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

this.t += 0.01;

Переменная `t` выступает в роли счётчика времени. Её инкремент на 0.01 каждый кадр задаёт скорость изменения угла вращения. Чем больше значение, тем быстрее вращение.

Ключевой метод вращения:

Phaser.Geom.Triangle.RotateAroundXY(this.triangle, this.rotateX, this.rotateY, Math.sin(this.t) * 0.05);

Статический метод RotateAroundXY() модифицирует исходный треугольник, поворачивая его вокруг точки с координатами (rotateX, rotateY). Угол поворота задаётся четвёртым аргументом: Math.sin(this.t) * 0.05. Использование синуса от времени `t` создаёт плавное колебательное (возвратно-поступательное) вращение вперёд и назад, а не непрерывное по кругу.

Отрисовка результата и визуализация центра

После вычисления новых координат треугольника и точки вращения, их необходимо отрисовать.

this.graphics.strokeTriangleShape(this.triangle);

Метод strokeTriangleShape() рисует контур (обводку) треугольника, используя заданный ранее стиль линии.

this.graphics.fillPoint(this.rotateX, this.rotateY, 4);

Для наглядности центр вращения визуализируется точкой. Метод fillPoint() рисует залитый круг с центром в (rotateX, rotateY) и радиусом 4 пикселя, используя стиль заливки, определённый при создании graphics. Это помогает сразу увидеть, вокруг какой именно точки происходит вращение.

Настройка игры и конфигурация

Весь пример запускается в стандартной конфигурации Phaser.

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

const game = new Phaser.Game(config);

Объект config определяет основные параметры: размеры canvas 800x600, автоматический выбор рендерера (WebGL или Canvas), ID родительского HTML-элемента и класс основной сцены. Создание экземпляра new Phaser.Game(config) инициализирует игру с этими настройками.

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

Метод Phaser.Geom.Triangle.RotateAroundXY предоставляет простой и эффективный способ реализовать вращение геометрической фигуры вокруг произвольной точки на сцене. Для экспериментов попробуйте изменить скорость, привязав её к this.time.now, или замените синусоидальное вращение на линейное, убрав Math.sin(). Можно создать несколько треугольников, вращающихся вокруг одного центра, или управлять координатами центра вращения (rotateX, rotateY) с помощью курсора мыши, используя this.input.activePointer.