О чем этот пример
В аркадных гонках, шутерах или играх с физикой часто нужно, чтобы спрайт поворачивался в сторону своего движения. Phaser 3 Arcade Physics позволяет сделать это одной строкой кода, связывая свойство `rotation` спрайта с углом вектора скорости. Этот подход идеален для снарядов, машинок, стрелок или любых объектов, чье направление должно визуально соответствовать их траектории. Мы разберем компактный пример, который демонстрирует эту технику и принцип работы Arcade Physics.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
arrow;
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('arrow', 'assets/sprites/arrow.png');
}
create ()
{
this.arrow = this.physics.add.image(400, 100, 'arrow')
.setVelocity(200, 0)
.setBounce(1, 1)
.setCollideWorldBounds(true);
}
update ()
{
this.arrow.rotation = this.arrow.body.angle;
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: {
debug: false,
gravity: { y: 600 }
}
},
scene: Example
};
const game = new Phaser.Game(config);
Настройка сцены и загрузка ассетов
Класс Example расширяет Phaser.Scene. В методе preload мы загружаем спрайт стрелки из удаленного репозитория.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('arrow', 'assets/sprites/arrow.png');
Здесь setBaseURL задает базовый путь для загрузки, что удобно для примеров. На практике вы, скорее всего, будете использовать локальные пути.
Создание физического тела и задание движения
В методе create мы создаем спрайт стрелки как физический объект Arcade Physics.
this.arrow = this.physics.add.image(400, 100, 'arrow')
.setVelocity(200, 0)
.setBounce(1, 1)
.setCollideWorldBounds(true);
* this.physics.add.image создает объект Image с физическим телом Arcade Physics.
* setVelocity(200, 0) сразу задает начальную горизонтальную скорость (200 пикселей в секунду).
* setBounce(1, 1) делает отскок от границ абсолютно упругим (коэффициент 1).
* setCollideWorldBounds(true) включает столкновение с границами игрового мира.
Важно: тело body у объекта появляется именно благодаря использованию this.physics.add.image.
Связывание вращения спрайта с углом скорости
Магия происходит в методе update, который вызывается на каждом кадре игры.
this.arrow.rotation = this.arrow.body.angle;
* this.arrow.body.angle — это свойство физического тела, которое автоматически вычисляет угол (в радианах) вектора текущей скорости (body.velocity).
* Присваивая это значение свойству rotation спрайта, мы заставляем его графику непрерывно поворачиваться в сторону движения.
Таким образом, когда стрелка отскакивает от стен и меняет вектор скорости, ее изображение мгновенно разворачивается по новому направлению.
Конфигурация игры и физики
Вся сцена инициализируется в объекте конфигурации.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: {
debug: false,
gravity: { y: 600 }
}
},
scene: Example
};
Обратите внимание на раздел physics. Здесь активируется система arcade и задается гравитация по оси Y. Несмотря на то что в данном примере стрелка движется горизонтально, гравитация влияет на ее поведение при отскоках.
Что попробовать дальше
Использование sprite.body.angle для управления rotation — это канонический и производительный способ синхронизации визуального представления объекта с его физическим движением в Phaser 3.
Для экспериментов попробуйте:
1. Изменить начальную скорость через setVelocity, чтобы увидеть, как угол вычисляется для разных векторов.
2. Применить эту технику к группе снарядов (physics.add.group).
3. Добавить управление с клавиатуры и убедиться, что спрайт игрока всегда смотрит в сторону последнего движения.
