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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        this.graphics = this.add.graphics({ lineStyle: { width: 3, color: 0x2266aa } });

        this.point = new Phaser.Math.Vector2(Math.random() - 0.5, Math.random() - 0.5);

        this.input.on('pointermove', pointer =>
        {
            this.point.copy(pointer);

            //  Set relative to center
            this.point.x -= 400;
            this.point.y -= 300;

            this.redraw();
        });

        this.redraw();
    }

    redraw ()
    {
        this.graphics.clear();

        this.point.setLength(250);

        this.graphics.lineBetween(400, 300, 400 + this.point.x, 300 + this.point.y);
    }
}

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

const game = new Phaser.Game(config);

Создание сцены и векторной точки

В методе create() сцены мы инициализируем графический объект для рисования линий и создаем случайный вектор. Исходный вектор this.point генерируется со случайными координатами в диапазоне от -0.5 до 0.5, что помещает его вблизи центра.

this.graphics = this.add.graphics({ lineStyle: { width: 3, color: 0x2266aa } });

this.point = new Phaser.Math.Vector2(Math.random() - 0.5, Math.random() - 0.5);

Затем мы подписываемся на событие движения указателя (pointermove), чтобы обновлять позицию вектора в реальном времени. Координаты указателя копируются в вектор, а затем смещаются относительно центра экрана (400, 300), чтобы вектор всегда начинался из центра.

this.input.on('pointermove', pointer =>
{
    this.point.copy(pointer);

    //  Смещение относительно центра
    this.point.x -= 400;
    this.point.y -= 300;

    this.redraw();
});

Метод setLength для управления длиной вектора

Ключевой метод redraw() очищает графику и устанавливает новую длину вектора. this.point.setLength(250) изменяет величину вектора до 250 пикселей, но сохраняет его первоначальное направление. Это означает, что вектор будет указывать туда же, куда и курсор, но всегда на фиксированном расстоянии от центра.

this.graphics.clear();

this.point.setLength(250);

this.graphics.lineBetween(400, 300, 400 + this.point.x, 300 + this.point.y);

Метод lineBetween рисует линию от центра экрана до конечной точки вектора, визуализируя результат. Важно: setLength модифицирует исходный вектор, а не возвращает новый.

Практическое применение в играх

В играх setLength() часто используется для нормализации векторов с последующим масштабированием. Например: - **Ограничение скорости**: Если вектор скорости объекта слишком длинный, можно установить максимальную длину. - **Сила выстрела**: Задать постоянную силу снаряда, независимо от расстояния до цели. - **Механика притяжения**: Создать вектор направления к объекту и задать ему фиксированную величину для силы притяжения.

Пример ограничения скорости движения персонажа:

// speedVector — вектор скорости персонажа
const maxSpeed = 200;
if (speedVector.length() > maxSpeed)
{
    speedVector.setLength(maxSpeed);
}

Этот подход эффективнее, чем ручной расчет через нормализацию и умножение.

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

Метод setLength() — это мощный инструмент для работы с векторами в Phaser, позволяющий легко управлять дистанцией и силой. Попробуйте изменить длину вектора в зависимости от времени или ввода игрока, или комбинируйте setLength с другими векторными операциями, например, add или scale, для создания сложных физических взаимодействий.