О чем этот пример
Визуализация динамических форм — ключ к созданию гипнотических фонов, эффектов заклинаний или индикаторов загрузки. В этом примере мы не просто рисуем эллипс, а оживляем его, заставляя плавно трансформироваться по заданной траектории. Мы разберем, как использовать методы геометрического смещения `Phaser.Geom.Ellipse.OffsetPoint` и вращения вектора `Phaser.Math.Rotate` для создания плавной анимации спирали без единого спрайта или текстуры, используя только Canvas API через `Graphics`. Это мощный прием для procedural-графики, который не нагружает память текстурами и работает на чистой математике.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
ellipse;
point;
step = 0.5;
graphics;
create ()
{
this.graphics = this.add.graphics({ fillStyle: { color: 0x00aaaa } });
this.ellipse = new Phaser.Geom.Ellipse(380, 280, 20, 0);
this.point = new Phaser.Math.Vector2(20, 0);
}
update ()
{
if (this.ellipse.y < 600)
{
this.graphics.fillEllipseShape(this.ellipse);
Phaser.Geom.Ellipse.OffsetPoint(this.ellipse, this.point);
Phaser.Math.Rotate(this.point, this.step);
this.ellipse.width = this.point.x;
this.ellipse.height = this.point.y;
this.step *= 0.996;
}
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Сцена и объекты: готовим холст
В методе create() инициализируются основные объекты для отрисовки. Создается экземпляр Graphics — наш инструмент для рисования фигур напрямую на канвасе. Затем определяется эллипс с нулевой начальной высотой и точка-вектор, которая будет управлять его изменением.
create ()
{
this.graphics = this.add.graphics({ fillStyle: { color: 0x00aaaa } });
this.ellipse = new Phaser.Geom.Ellipse(380, 280, 20, 0);
this.point = new Phaser.Math.Vector2(20, 0);
}
Сердце анимации: цикл update
Каждый кадр в update() эллипс рисуется на экране с текущими параметрами. После отрисовки его позиция смещается на значение вектора this.point с помощью статического метода Phaser.Geom.Ellipse.OffsetPoint. Это ключевой момент: эллипс не просто меняет размер, а движется в пространстве.
if (this.ellipse.y < 600)
{
this.graphics.fillEllipseShape(this.ellipse);
Phaser.Geom.Ellipse.OffsetPoint(this.ellipse, this.point);
}
Динамика формы: вращение и масштабирование
Чтобы траектория движения закручивалась, вектор this.point вращается на небольшой угол this.step с помощью Phaser.Math.Rotate. Затем ширина и высота эллипса обновляются значениями X и Y этого вектора, что создает эффект "раскручивания". Постепенное уменьшение угла шага (this.step *= 0.996) замедляет вращение, формируя плавное затухание спирали.
Phaser.Math.Rotate(this.point, this.step);
this.ellipse.width = this.point.x;
this.ellipse.height = this.point.y;
this.step *= 0.996;
Конфигурация игры: минимальный шаблон
Это стандартная конфигурация для запуска примера Phaser. Важно, что здесь используется type: Phaser.AUTO, что позволяет движку самому выбрать рендерер (WebGL или Canvas).
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Вы освоили механизм procedural-анимации геометрических фигур, комбинируя смещение и вращение. Для экспериментов попробуйте изменить начальный цвет или стиль fillStyle, добавьте градиент, управляйте шагом this.step в зависимости от времени или ввода с клавиатуры. Можно создать несколько эллипсов с разными начальными точками для сложных паттернов или привязать анимацию к здоровью персонажа, где спираль будет визуальным индикатором.
