О чем этот пример
Реализация движения объектов к заданной точке — частая задача в играх: от преследования врагом игрока до отправки снаряда в цель. Phaser 3 предлагает для этого элегантное решение в рамках Arcade Physics. В этой статье мы разберем, как заставить спрайт плавно двигаться к цели с заданной скоростью, используя встроенный метод `physics.moveToObject`. Этот подход избавляет от ручных вычислений векторов и идеально подходит для прототипирования механик преследования или запуска снарядов.
Версия 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('flower', 'assets/sprites/flower-exo.png');
this.load.image('cursor', 'assets/sprites/drawcursor.png');
}
create ()
{
const flower = this.physics.add.image(100, 300, 'flower')
.setBounce(1, 1)
.setCollideWorldBounds(true);
const cursor = this.add.image(0, 0, 'cursor').setVisible(false);
this.add.text(10, 10, 'Click to set target', { fill: '#00ff00' });
this.input.on('pointerdown', (pointer) =>
{
cursor.copyPosition(pointer).setVisible(true);
// Move toward target at 200 px/s:
this.physics.moveToObject(flower, cursor, 200);
// See <move and stop at position.js> for stopping.
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: { debug: true }
},
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и объектов
В методе preload загружаются два изображения: главный объект flower и курсор-цель cursor. Обратите внимание, что пример использует базовый URL для загрузки ассетов из репозитория примеров Phaser.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('flower', 'assets/sprites/flower-exo.png');
this.load.image('cursor', 'assets/sprites/drawcursor.png');
}
В create создается физический спрайт flower. Ключевые моменты: использование this.physics.add.image и настройка свойств физики. Метод setBounce(1, 1) делает объект абсолютно упругим, а setCollideWorldBounds(true) — ограничивает его движение границами мира. Объект cursor создается как обычное изображение и изначально скрыт.
const flower = this.physics.add.image(100, 300, 'flower')
.setBounce(1, 1)
.setCollideWorldBounds(true);
const cursor = this.add.image(0, 0, 'cursor').setVisible(false);
Обработка клика и установка цели
Пользовательский интерфейс прост: текст-подсказка и обработчик события клика (pointerdown). При клике позиция курсора (скрытого спрайта cursor) обновляется, и он становится видимым. Это визуализирует точку, к которой будет двигаться цветок.
this.add.text(10, 10, 'Click to set target', { fill: '#00ff00' });
this.input.on('pointerdown', (pointer) =>
{
cursor.copyPosition(pointer).setVisible(true);
// ... Движение будет здесь
});
Метод copyPosition() копирует координаты указателя мыши в спрайт cursor.
Важно: cursor — это не физическое тело, а обычный спрайт, используемый лишь как визуальный маркер и целевая точка для вычислений.
Магия метода physics.moveToObject
Вся логика движения умещается в одну строку внутри обработчика клика. Метод this.physics.moveToObject автоматически вычисляет вектор скорости для физического тела (flower), чтобы оно начало движение к целевому объекту (cursor) с указанной постоянной скоростью.
// Move toward target at 200 px/s:
this.physics.moveToObject(flower, cursor, 200);
**Что происходит внутри:**
1. Система физики Arcade берет текущие мировые координаты flower и cursor.
2. Рассчитывается направление от цветка к курсору.
3. Устанавливаются свойства body.velocity.x и body.velocity.y спрайта flower таким образом, чтобы результирующая скорость (длина вектора) была равна 200 пикселей в секунду.
4. Движение начинается мгновенно. Объект будет продолжать движение с этой скоростью и направлением, пока его скорость не будет изменена другим кодом или физическим взаимодействием (например, столкновением).
**Важное замечание:** В этом примере объект не останавливается при достижении цели. Он будет двигаться дальше, пока не столкнется с границей мира и не отскочит от нее (благодаря setBounce(1, 1)).
Конфигурация игры и физики
Для работы примера необходима правильная настройка конфигурации игры. Самое важное — активация физического движка Arcade и включение отладки.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
physics: {
default: 'arcade', // Используем Arcade Physics
arcade: { debug: true } // Включаем отладочные отображение хитбоксов
},
scene: Example
};
Параметр debug: true подсвечивает физические тела (цветок) зеленой рамкой, что позволяет наглядно видеть его границы и убедиться, что движение и отскок работают корректно. В продакшене его обычно отключают.
Что попробовать дальше
Метод physics.moveToObject — это мощный и лаконичный инструмент для реализации движения к цели в Phaser 3. Он идеально подходит для быстрого прототипирования механик, где требуется «запустить объект из точки A в точку B». Для дальнейших экспериментов попробуйте: изменить скорость в зависимости от расстояния до цели; реализовать остановку объекта при достижении цели (используя проверку расстояния в update); применить метод к группе объектов, чтобы создать «рой» преследователей; или комбинировать его с другими силами Arcade Physics, такими как ускорение или трение.
