О чем этот пример
Создание плавной анимации геометрических фигур — мощный инструмент для визуальных эффектов в играх. Этот пример показывает, как можно в реальном времени генерировать и визуализировать сложные полигональные формы, например, для магических заклинаний, нестандартных интерфейсов или фоновых анимаций. Мы разберем, как использовать класс `Phaser.Geom.Polygon` и его ключевой метод `setTo()` для динамического обновления фигуры на основе математических формул. Вы научитесь превращать простые математические выражения в захватывающие визуальные паттерны.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
graphics;
angle = 0;
radius = 100;
points;
polygon;
create ()
{
this.graphics = this.add.graphics({ lineStyle: { width: 2, color: 0xaa6622 } });
this.polygon = new Phaser.Geom.Polygon();
this.points = [];
}
update ()
{
if (this.angle <= Math.PI * 2)
{
this.angle += Math.PI / 30;
const leafSize = 150 * Math.sin((this.angle * 2) % Math.PI);
this.points.push(400 + Math.cos(this.angle) * (this.radius + leafSize));
this.points.push(300 + Math.sin(this.angle) * (this.radius + leafSize));
this.polygon.setTo(this.points);
this.graphics.clear();
this.graphics.strokePoints(this.polygon.points);
}
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Инициализация: Подготовка холста и объектов
В методе create() происходит базовая настройка сцены. Создается объект Graphics для рисования линий и пустой полигон.
this.graphics = this.add.graphics({ lineStyle: { width: 2, color: 0xaa6622 } });
this.polygon = new Phaser.Geom.Polygon();
this.points = [];
Объект this.graphics — это наш инструмент для отрисовки. Мы задаем ему стиль линии: толщину 2 пикселя и цвет (шестнадцатеричный код 0xaa6622). Phaser.Geom.Polygon — это геометрический объект, представляющий многоугольник. Изначально он пуст. Массив this.points будет хранить последовательность координат (x, y) для вершин нашего полигона.
Магия в update(): Генерация точек по формуле
Сердце анимации находится в методе update(), который вызывается на каждом кадре. Пока угол не превысит полный круг (2π), мы добавляем новую точку.
if (this.angle <= Math.PI * 2)
{
this.angle += Math.PI / 30;
const leafSize = 150 * Math.sin((this.angle * 2) % Math.PI);
this.points.push(400 + Math.cos(this.angle) * (this.radius + leafSize));
this.points.push(300 + Math.sin(this.angle) * (this.radius + leafSize));
Каждый шаг увеличивает угол. Переменная leafSize создает осцилляцию с двойной частотой, используя Math.sin. Это создает "лепестковый" эффект. Далее в массив points последовательно добавляются координаты X и Y. Формула 400 + Math.cos(angle) * (radius + leafSize) рассчитывает позицию точки на основе центра (400, 300), базового радиуса и динамического смещения leafSize.
Ключевой метод: setTo() и перерисовка
После добавления новых координат в массив, необходимо сообщить полигону о его новых границах. Именно для этого и существует метод setTo().
this.polygon.setTo(this.points);
this.graphics.clear();
this.graphics.strokePoints(this.polygon.points);
Метод setTo() полностью перезаписывает вершины полигона, принимая плоский массив чисел [x1, y1, x2, y2, ...]. После обновления геометрии мы очищаем предыдущий кадр с помощью clear() и рисуем новый контур полигона методом strokePoints(), который принимает массив объектов точек из polygon.points. Без вызова setTo() полигон оставался бы пустым, и отрисовки бы не происходило.
Сборка сцены: Конфигурация игры
Весь пример завершается стандартной для Phaser 3 конфигурацией игры, которая указывает размеры холста и корневой класс сцены.
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Этот блок кода создает экземпляр игры Phaser. Параметр scene: Example указывает, что наш класс Example будет использоваться в качестве основной сцены. Размер игрового поля устанавливается в 800x600 пикселей.
Что попробовать дальше
Метод setTo() класса Phaser.Geom.Polygon — это прямой способ динамического управления формой. Вы можете экспериментировать, меняя формулу для leafSize — попробуйте использовать Math.cos вместо sin или добавить больше множителей к углу. Также интересно изменять базовый radius со временем или использовать другие примитивы Graphics, например fillPoints(), для заливки фигуры цветом. Это открывает двери к созданию процедурных анимаций для ауры персонажей, анимированных порталов или уникальных траекторий движения.
