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

Для разработки игр часто требуется точная работа с геометрией: определить позицию снаряда на траектории, рассчитать движение по пути или разместить объект в определённой точке маршрута. В этом примере мы разберём, как использовать класс `Phaser.Geom.Line` для вычисления координат точки, находящейся на заданном расстоянии от начала отрезка. Этот подход — фундамент для создания траекторий, путей следования и любых линейных интерполяций в вашей игре.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics();

        const line = new Phaser.Geom.Line(200, 300, 700, 100);

        graphics.lineStyle(1, 0x00aa00);

        graphics.strokeLineShape(line);

        const x = line.x1 + (line.x2 - line.x1) * 0.1;
        const y = line.y1 + (line.y2 - line.y1) * 0.1;

        graphics.fillStyle(0xff0000);

        graphics.fillRect(x, y, 6, 6);
    }
}

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

const game = new Phaser.Game(config);

Что делает этот код?

Пример создаёт сцену, рисует зелёную линию от точки (200, 300) до точки (700, 100), а затем вычисляет и отрисовывает красную точку на этой линии. Точка расположена на расстоянии 10% от начала линии (от первой точки ко второй).

Визуально это выглядит так: на экране отображается отрезок и маленький красный квадрат, показывающий вычисленную позицию. Это базовый, но мощный приём для работы с линейными зависимостями в игровой логике.

Создание линии и её визуализация

В методе create() сцены сначала создаётся объект Graphics для рисования примитивов.

Затем создаётся объект линии Phaser.Geom.Line. Первые два аргумента конструктора — это координаты X и Y начальной точки, следующие два — координаты конечной точки.

Для отрисовки контура линии задаётся стиль с помощью graphics.lineStyle() и затем линия рисуется методом strokeLineShape().

const graphics = this.add.graphics();
const line = new Phaser.Geom.Line(200, 300, 700, 100);

graphics.lineStyle(1, 0x00aa00);
graphics.strokeLineShape(line);

Вычисление координат точки на линии

Ключевая часть примера — расчёт координат точки, которая делит отрезок в заданной пропорции. Здесь используется принцип линейной интерполяции (LERP).

Формула для нахождения точки, находящейся на доли `t` (от 0 до 1) от начала линии: - x = x1 + (x2 - x1) * t - y = y1 + (y2 - y1) * t

В исходном коде значение `tзадано как 0.1, что означает 10% пути от первой точки ко второй. Мы получаем новые координатыxиy`.

const x = line.x1 + (line.x2 - line.x1) * 0.1;
const y = line.y1 + (line.y2 - line.y1) * 0.1;

Отрисовка вычисленной точки

После вычисления координат необходимо их визуализировать. Меняем стиль заливки у объекта graphics на красный цвет и рисуем небольшой квадрат (размером 6x6 пикселя) с центром в вычисленных координатах.

Метод fillRect() принимает координаты левого верхнего угла прямоугольника. Поскольку мы хотим, чтобы точка была отцентрирована на координатах (x, y), квадрат рисуется со смещением на половину своей ширины и высоты (что в данном случае составляет 3 пикселя).

graphics.fillStyle(0xff0000);
graphics.fillRect(x, y, 6, 6);

Как применить это в реальной игре?

Вместо константы 0.1 можно использовать переменную, значение которой меняется со временем, создавая анимацию движения объекта вдоль линии. Это основа для: - Движения снаряда по прямой траектории. - Перемещения камеры по заданному маршруту. - Плавного перехода (интерполяции) между двумя позициями любого игрового объекта.

// Пример: движение с постоянной скоростью
let t = 0; // Доля пройденного пути (от 0 до 1)

function update(time, delta) {
    t += 0.001; // Увеличиваем долю пути на каждом кадре
    if (t > 1) t = 1; // Ограничиваем конечной точкой

    const spriteX = line.x1 + (line.x2 - line.x1) * t;
    const spriteY = line.y1 + (line.y2 - line.y1) * t;

    // Перемещаем спрайт на новые координаты
    mySprite.setPosition(spriteX, spriteY);
}

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

Работа с Phaser.Geom.Line и линейной интерполяцией открывает множество возможностей для управления движением и позиционированием в игре. Вы можете экспериментировать: попробуйте менять коэффициент `t` в зависимости от времени или ввода игрока, создайте путь из нескольких отрезков или используйте этот метод для расчёта точки столкновения снаряда с траекторией. Понимание этой базовой геометрической операции — большой шаг к созданию сложной и плавной игровой механики.