О чем этот пример
Векторы — основа игровой физики, анимации и логики. Умение работать с ними напрямую влияет на реалистичность поведения объектов. В этом примере мы не просто разделим вектор на скаляр, а создадим интерактивную визуализацию, которая наглядно покажет, как последовательное деление координат вектора создаёт геометрические паттерны. Этот подход поможет глубже понять, как математические операции трансформируют игровое пространство.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
this.graphics = this.add.graphics({ fillStyle: { color: 0x2266aa } });
this.input.on('pointermove', pointer =>
{
this.redraw(1.01 + pointer.x / 800, 1.01 + pointer.y / 600);
});
this.redraw(1.2, 1.2);
}
redraw (divX, divY)
{
this.graphics.clear();
const point = new Phaser.Math.Vector2(800, 600);
while (point.x > 10 || point.y > 10)
{
this.graphics.fillPointShape(point, 20);
point.x /= divX;
point.y /= divY;
}
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и интерактивности
В методе create() инициализируется сцена. Создаётся объект Graphics для отрисовки примитивов — в нашем случае, точек. Затем на событие перемещения указателя (pointermove) вешается обработчик. Координаты курсора (pointer.x, pointer.y) нормализуются, чтобы получить удобные для расчёта делители в диапазоне примерно от 1 до 2. Эти делители передаются в основную функцию перерисовки redraw().
create ()
{
this.graphics = this.add.graphics({ fillStyle: { color: 0x2266aa } });
this.input.on('pointermove', pointer =>
{
this.redraw(1.01 + pointer.x / 800, 1.01 + pointer.y / 600);
});
this.redraw(1.2, 1.2);
}
Сердце примера: функция redraw и деление вектора
Функция redraw(divX, divY) отвечает за всю визуализацию. В её начале холст очищается вызовом this.graphics.clear(). Затем создаётся исходный вектор point с координатами (800, 600) — это правая нижняя часть экрана в нашем примере.
Ключевой процесс происходит в цикле while. Пока хотя бы одна из координат вектора больше 10, выполняется два действия:
1. Текущее положение вектора отрисовывается на холсте как закрашенная точка.
2. Координаты вектора point делятся на переданные делители divX и divY.
Операция point.x /= divX — это сокращённая запись point.x = point.x / divX. Таким образом, на каждой итерации вектор "сдвигается" к началу координат (0, 0), создавая последовательность точек.
redraw (divX, divY)
{
this.graphics.clear();
const point = new Phaser.Math.Vector2(800, 600);
while (point.x > 10 || point.y > 10)
{
this.graphics.fillPointShape(point, 20);
point.x /= divX;
point.y /= divY;
}
}
Как работает цикл и формируется узор
Цикл while (point.x > 10 || point.y > 10) гарантирует, что отрисовка остановится, когда вектор приблизится к началу координат (условие выхода — обе координаты меньше или равны 10). Начальная точка — (800, 600). После первого деления координаты становятся, например, (800/1.5, 600/1.2). Процесс повторяется, и каждая новая точка ложится ближе к (0,0).
Разные делители для X и Y (divX и divY) приводят к тому, что координаты уменьшаются с разной скоростью. Если divX больше divY, то X-координата будет сокращаться быстрее, и траектория точек сильнее "завалится" по вертикали. Именно это позволяет управлять формой паттерна движением мыши. Без условия > 10 цикл стал бы бесконечным, так как деление никогда не даст точного нуля.
Конфигурация игры и запуск
Стандартный конфигурационный объект Phaser config задаёт размеры холста, автоматический выбор рендерера (Phaser.AUTO), элемент-контейнер и нашу сцену Example. Инстанс игры new Phaser.Game(config) запускает весь процесс.
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Пример превращает абстрактную операцию деления вектора в наглядный интерактивный инструмент. Вы увидели, как с помощью Phaser.Math.Vector2 и Graphics можно создавать динамические визуализации для отладки или обучения. Для экспериментов попробуйте: изменить начальную точку вектора; заменить деление на умножение или сложение; использовать один общий делитель для обеих координат; или рисовать не точки, а линии между итерациями, чтобы увидеть траекторию.
