О чем этот пример
Работа с геометрией — фундаментальный навык для создания игровой логики, визуальных эффектов и траекторий движения. В этой статье разберем пример, который демонстрирует не статичное рисование, а динамическое смещение целой геометрической фигуры — круга. Это полезно для создания орбит, волновых эффектов, рассеивания объектов или алгоритмической генерации узоров, где положение центра фигуры меняется по заданному закону.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
const circle = new Phaser.Geom.Circle(350, 150, 50);
const graphics = this.add.graphics({ lineStyle: { color: 0x00ff00 } });
graphics.strokeCircleShape(circle);
for (let i = 0; i < 10; i++)
{
const angle = i / 10 * Phaser.Math.PI2;
const xOffset = Math.cos(angle) * circle.diameter;
const yOffset = Math.sin(angle) * circle.diameter;
Phaser.Geom.Circle.Offset(circle, xOffset, yOffset);
graphics.strokeCircleShape(circle);
}
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Разбор примера: что делает код?
Исходный код создает один круг и последовательно смещает его центр, отрисовывая новое положение на каждом шаге. В итоге мы видим не один, а десять концентрических окружностей, разбросанных по экрану.
Ключевые этапы: 1. Создание исходного круга. 2. Его первичная отрисовка. 3. Цикл, в котором вычисляется смещение и применяется к фигуре. 4. Отрисовка круга в его новом положении после каждого смещения.
Этот подход отличается от простого рисования нескольких кругов в разных координатах. Здесь мы модифицируем единственный геометрический объект, что может быть полезно для его дальнейшего использования в физических расчетах или проверках коллизий.
Создание и первичная отрисовка фигуры
В методе create() сцены создается объект круга с помощью класса Phaser.Geom.Circle. Его конструктор принимает три аргумента: координаты центра по осям X и Y и радиус.
const circle = new Phaser.Geom.Circle(350, 150, 50);
Затем создается объект Graphics для рисования и зеленым цветом отрисовывается контур (stroke) созданного круга.
const graphics = this.add.graphics({ lineStyle: { color: 0x00ff00 } });
graphics.strokeCircleShape(circle);
Математика смещения: от угла к вектору
Сердце примера — цикл, который 10 раз вычисляет новое положение круга. Для этого используется тригонометрия.
1. Вычисляется угол в радианах для текущего шага `i. ЗначениеPhaser.Math.PI2— это константа, равная2 * Math.PI`, то есть полному обороту в 360 градусов.
const angle = i / 10 * Phaser.Math.PI2;
2. На основе этого угла вычисляются компоненты вектора смещения. Косинус дает X-компоненту, синус — Y-компоненту. Длина этого вектора равна диаметру исходного круга (circle.diameter).
const xOffset = Math.cos(angle) * circle.diameter;
const yOffset = Math.sin(angle) * circle.diameter;
Таким образом, на каждом шаге мы получаем вектор, направленный в разные стороны (равномерно распределенные по окружности), длиной в 100 пикселей.
Применение смещения к геометрическому объекту
Полученные значения xOffset и yOffset передаются в статический метод Phaser.Geom.Circle.Offset. **Важно понимать:** этот метод не создает новый круг, а модифицирует переданный ему объект circle, добавляя смещение к его текущим координатам центра.
Phaser.Geom.Circle.Offset(circle, xOffset, yOffset);
После вызова этого метода координаты центра круга circle.x и circle.y изменяются. Затем обновленная фигура снова отрисовывается.
graphics.strokeCircleShape(circle);
Поскольку объект graphics один и тот же, а круг после каждого смещения находится в новом месте, на холсте накапливаются все 10 позиций, создавая итоговый узор.
Конфигурация и запуск игры
Код завершается стандартной для Phaser 3 конфигурацией игры. В ней указывается размер холста, тип рендерера, элемент на странице для встраивания и класс сцены, содержащий нашу логику.
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Метод Phaser.Geom.Circle.Offset — это мощный инструмент для procedural-генерации и динамического управления положением фигур. Вместо того чтобы управлять множеством объектов, вы можете трансформировать один. Попробуйте поэкспериментировать: измените множитель длины вектора смещения, используйте не равномерное распределение углов, примените смещение к другим геометрическим объектам (например, Phaser.Geom.Rectangle) или свяжите смещение с реальным временем в методе update(), чтобы круг плавно "бегал" по экрану по сложной траектории.
