О чем этот пример
В разработке игр часто возникает задача динамического изменения формы объектов, например, для создания анимации ломаной брони, меняющихся силуэтов или геометрических эффектов. Статичная геометрия быстро становится скучной. Класс `Phaser.Geom.Triangle` в Phaser предоставляет мощный метод `setTo()` для программного переопределения вершин треугольника. В этой статье мы разберем, как использовать этот метод для создания каскадных геометрических трансформаций, что открывает двери к созданию сложных визуальных механик без использования тяжеловесных спрайтов или анимаций.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
const triangle = new Phaser.Geom.Triangle(400, 250, 300, 350, 500, 350);
const graphics = this.add.graphics({ lineStyle: { color: 0xaaaa00 } });
graphics.strokeTriangleShape(triangle);
for (let i = 0; i < 25; i++)
{
triangle.setTo(
triangle.x1 * 0.97, triangle.y1 * 0.95,
triangle.x2 * 1.05, triangle.y2 * 1.04,
triangle.x3 * 1.02, triangle.y3 * 1.01
);
graphics.strokeTriangleShape(triangle);
}
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Создание базового треугольника
Вся работа начинается с создания экземпляра геометрического треугольника. Конструктор класса Phaser.Geom.Triangle принимает шесть аргументов – координаты X и Y для каждой из трех вершин.
const triangle = new Phaser.Geom.Triangle(400, 250, 300, 350, 500, 350);
Этот код создает треугольник с вершинами в точках (400, 250), (300, 350) и (500, 350). Для его визуализации мы используем объект Graphics, который позволяет рисовать примитивы.
const graphics = this.add.graphics({ lineStyle: { color: 0xaaaa00 } });
graphics.strokeTriangleShape(triangle);
Здесь мы создаем контекст рисования с желтым (0xaaaa00) стилем линии и отрисовываем контур нашего треугольника с помощью метода strokeTriangleShape().
Магия метода `setTo()`
Ключевой инструмент трансформации – метод setTo(). Он не создает новый объект, а перезаписывает координаты существующего треугольника. Это эффективно с точки зрения производительности.
Сигнатура метода:
triangle.setTo(x1, y1, x2, y2, x3, y3);
Каждый вызов полностью заменяет старые координаты вершины 1 (x1, y1), вершины 2 (x2, y2) и вершины 3 (x3, y3) на новые значения. В исходном примере новые координаты вычисляются на основе старых, что и создает анимацию.
triangle.setTo(
triangle.x1 * 0.97, triangle.y1 * 0.95,
triangle.x2 * 1.05, triangle.y2 * 1.04,
triangle.x3 * 1.02, triangle.y3 * 1.01
);
Здесь каждая вершина меняется по своему закону: первая сжимается к центру (умножение на 0.97 и 0.95), вторая и третья – расширяются (умножение на значения больше 1).
Цикл трансформации и отрисовки
Для создания последовательности кадров (множества треугольников) используется простой цикл. На каждой итерации мы:
1. Вычисляем новые координаты и применяем их через setTo().
2. Отрисовываем текущее состояние треугольника.
for (let i = 0; i < 25; i++)
{
// 1. Трансформируем треугольник
triangle.setTo(
triangle.x1 * 0.97, triangle.y1 * 0.95,
triangle.x2 * 1.05, triangle.y2 * 1.04,
triangle.x3 * 1.02, triangle.y3 * 1.01
);
// 2. Отрисовываем новый контур
graphics.strokeTriangleShape(triangle);
}
Поскольку объект Graphics не очищается, каждый новый вызов strokeTriangleShape() добавляет в сцену контур треугольника в его новой позиции и форме. В результате мы видим не одно движущееся изображение, а след из 26 треугольников (исходный + 25 новых), что создает эффект постепенного искажения и движения.
Конфигурация игры и запуск сцены
Код примера является полноценным приложением Phaser. Конфигурационный объект задает основные параметры игры: размеры холста, тип рендерера и корневую сцену.
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example // Наш класс сцены
};
const game = new Phaser.Game(config);
После создания экземпляра Phaser.Game с этой конфигурацией фреймворк автоматически инициализирует рендерер и запустит жизненный цикл сцены Example, вызвав в нужный момент метод create(), который мы и разобрали.
Что попробовать дальше
Метод setTo() для геометрических объектов в Phaser – это простой, но мощный способ анимировать форму напрямую, минуя систему анимаций спрайтов. Он идеально подходит для процедурной графики, визуальных эффектов и динамических коллайдеров.
**Идеи для экспериментов:**
1. Свяжите изменение вершин треугольника с игровыми событиями (например, с каждым выстрелом).
2. Используйте Math.sin() или Math.cos() для вычисления новых координат, чтобы получить плавные колебания формы.
3. Примените этот же принцип к другим геометрическим объектам, например, Phaser.Geom.Rectangle, чтобы искажать игровые платформы или зоны поражения.
4. Комбинируйте setTo() с заливкой (graphics.fillTriangleShape), используя разные цвета на каждой итерации для создания градиентных эффектов.
