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

Визуализация и управление движением — основа любой динамичной игры. В этом примере мы разберем, как с помощью простого сложения векторов (`Phaser.Math.Vector2.add`) создается плавная, волнообразная траектория. Этот подход — фундамент для реализации полета снарядов, движения врагов по патрульным маршрутам или создания органических анимаций, где объект должен двигаться не просто по прямой, а по сложной, вычисляемой траектории.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics({ fillStyle: { color: 0x2266aa } });

        const point = new Phaser.Math.Vector2(0, 300);
        const point2 = new Phaser.Math.Vector2(0, 0);

        for (let angle = 0; point.x < 800; angle += Math.PI / 18)
        {
            graphics.fillPointShape(point, 20);

            point2.set(20, Math.cos(angle) * 40);

            point.add(point2);
        }
    }
}

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

const game = new Phaser.Game(config);

Создание сцены и графики

В методе create сцены инициализируются основные объекты для рисования и хранения координат. Объект graphics будет использоваться для отрисовки точек на экране.

const graphics = this.add.graphics({ fillStyle: { color: 0x2266aa } });

Создаются два вектора. Вектор point — это основная позиция, которая будет двигаться и визуализироваться. Вектор point2 — это вспомогательный вектор смещения, который будет обновляться на каждом шаге цикла.

const point = new Phaser.Math.Vector2(0, 300);
const point2 = new Phaser.Math.Vector2(0, 0);

Цикл анимации и расчет смещения

Движение точки организуется в цикле for. Условие point.x < 800 гарантирует, что анимация будет рисоваться только в пределах ширины холста (800 пикселей). На каждой итерации сначала рисуется текущая позиция point.

graphics.fillPointShape(point, 20);

Затем рассчитывается новое значение вектора смещения point2. Его X-компонента всегда равна 20 (постоянный шаг вправо), а Y-компонента вычисляется с помощью косинуса, что и создает волнообразный паттерн.

point2.set(20, Math.cos(angle) * 40);

Ключевая операция: сложение векторов

Сердце примера — метод add. Он модифицирует исходный вектор point, прибавляя к его текущим координатам (x, y) значения из вектора point2. Таким образом, новая позиция точки равна сумме старой позиции и вычисленного смещения.

point.add(point2);

После этого угол увеличивается для следующего кадра, и цикл повторяется, пока точка не выйдет за правую границу экрана. Именно последовательное сложение вектора позиции с изменяющимся вектором смещения и порождает финальную траекторию.

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

Этот пример демонстрирует мощь векторной алгебры в игровой логике: сложное движение разбивается на простые, повторяющиеся операции. Для экспериментов попробуйте заменить Math.cos на Math.sin или изменить множитель 40 для управления амплитудой волны. Можно заменить точку на спрайт и использовать этот же принцип в update для создания движения врага или астероида по синусоидальной траектории.