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

Управление движением объектов по заданным путям — ключевой элемент для создания платформеров, стратегий или игр с тактическим перемещением. В этом примере показано, как использовать встроенные методы Phaser для приостановки и возобновления следования спрайта по кривой. Это позволяет реализовать базовую логику паузы для патрулирующих врагов, управляемых игроком платформ или любых анимаций, требующих интерактивного контроля. Пример демонстрирует работу с `Follower`, объектом, который следует по `Curve`. Мы создадим сплайн-путь, запустим по нему спрайт в бесконечном цикле и добавим возможность по клику мыши ставить движение на паузу и возобновлять его, используя методы `pauseFollow()` и `resumeFollow()`.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('lemming', 'assets/sprites/lemming.png');
    }

    create ()
    {
        const points = [];

        points.push(new Phaser.Math.Vector2(50, 400));
        points.push(new Phaser.Math.Vector2(200, 200));
        points.push(new Phaser.Math.Vector2(350, 300));
        points.push(new Phaser.Math.Vector2(500, 500));
        points.push(new Phaser.Math.Vector2(700, 400));

        const curve = new Phaser.Curves.Spline(points);

        const graphics = this.add.graphics();

        graphics.lineStyle(1, 0xffffff, 1);

        curve.draw(graphics, 64);

        graphics.fillStyle(0x00ff00, 1);

        for (let i = 0; i < points.length; i++)
        {
            graphics.fillCircle(points[i].x, points[i].y, 4);
        }

        const lemming = this.add.follower(curve, 50, 400, 'lemming');

        lemming.startFollow({
            duration: 6000,
            yoyo: true,
            repeat: -1,
            rotateToPath: true
        });

        this.input.on('pointerdown', () =>
        {

            if (lemming.isFollowing())
            {
                lemming.pauseFollow();
            }
            else
            {
                lemming.resumeFollow();
            }

        });

    }
}

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

const game = new Phaser.Game(config);

Создание пути и объекта-последователя

В первую очередь необходимо определить путь, по которому будет двигаться объект. В Phaser для этого используется система кривых (Curves).

Создадим массив точек и на его основе построим сплайн (Spline) — плавную кривую, проходящую через все заданные точки. Затем добавим графику для визуализации этого пути и контрольных точек.

const points = [];
points.push(new Phaser.Math.Vector2(50, 400));
points.push(new Phaser.Math.Vector2(200, 200));
points.push(new Phaser.Math.Vector2(350, 300));
points.push(new Phaser.Math.Vector2(500, 500));
points.push(new Phaser.Math.Vector2(700, 400));

const curve = new Phaser.Curves.Spline(points);

const graphics = this.add.graphics();
graphics.lineStyle(1, 0xffffff, 1);
curve.draw(graphics, 64);
graphics.fillStyle(0x00ff00, 1);
for (let i = 0; i < points.length; i++)
{
    graphics.fillCircle(points[i].x, points[i].y, 4);
}

Теперь создадим сам движущийся объект — последователя (Follower). Фабричный метод this.add.follower() принимает кривую, стартовые координаты (они будут проигнорированы, так как путь задан кривой) и ключ текстуры спрайта.

const lemming = this.add.follower(curve, 50, 400, 'lemming');

Запуск движения с параметрами

Чтобы объект начал двигаться, необходимо вызвать метод startFollow(). Этот метод принимает конфигурационный объект, который позволяет тонко настроить анимацию перемещения.

lemming.startFollow({
    duration: 6000,
    yoyo: true,
    repeat: -1,
    rotateToPath: true
});

Разберем ключевые параметры: * duration: 6000 — время в миллисекундах, за которое объект пройдет весь путь от начала до конца. Здесь это 6 секунд. * yoyo: true — включает режим "йо-йо". После достижения конца пути объект развернется и пойдет обратно к началу. * repeat: -1 — количество повторений. Значение -1 задает бесконечное повторение движения. * rotateToPath: true — важная опция, которая автоматически поворачивает спрайт по направлению движения. Это критично для объектов, которые должны смотреть "по курсу", например, машинок или персонажей.

Интерактивное управление движением

Ядро примера — интерактивное управление процессом следования. Мы добавим слушатель события клика мыши (pointerdown), который будет проверять состояние последователя и в зависимости от него приостанавливать или возобновлять движение.

this.input.on('pointerdown', () => {
    if (lemming.isFollowing())
    {
        lemming.pauseFollow();
    }
    else
    {
        lemming.resumeFollow();
    }
});

Логика работы: 1. lemming.isFollowing() — этот метод возвращает true, если в данный момент объект активно следует по пути. Он учитывает состояние паузы. Если движение на паузе, метод вернет false. 2. lemming.pauseFollow() — приостанавливает анимацию движения объекта. Объект остается на своем текущем месте на кривой. 3. lemming.resumeFollow() — возобновляет анимацию движения с того места, где она была остановлена.

Таким образом, каждый клик по сцене работает как переключатель: движение есть → пауза, пауза → движение.

Конфигурация игры и запуск сцены

Весь описанный код находится внутри класса сцены (Example). Для запуска игры необходимо создать базовую конфигурацию и инстанс Phaser.Game.

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

const game = new Phaser.Game(config);

Эта конфигурация задает: * type: Phaser.AUTO — автоматический выбор рендерера (WebGL или Canvas). * Размеры игрового холста 800x600 пикселей. * Темно-серый фоновый цвет (#2d2d2d). * Родительский HTML-элемент с id phaser-example, куда будет встроен canvas. * Класс главной сцены — Example.

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

Использование методов pauseFollow() и resumeFollow() предоставляет простой и эффективный способ добавить интерактивность в перемещение объектов по путям. Этот механизм отлично подходит для реализации поведения врагов (например, остановка при обнаружении игрока), управления анимациями в кат-сценах или создания элементов пазлов, где игрок должен контролировать движение платформ. Для экспериментов попробуйте: 1. Изменить параметры пути в startFollow(), например, убрать yoyo или задать конечное число repeat. 2. Связать паузу не с кликом мыши, а с другими событиями, например, с пересечением зоны (overlap) другим спрайтом. 3. Создать несколько последователей на одном или разных путях и управлять их паузой независимо.