О чем этот пример
Физический движок Arcade в Phaser предоставляет гибкий контроль над гравитацией, что является ключевым для создания реалистичного поведения объектов. В этой статье мы разберем, как работает гравитация на уровне мира и на уровне отдельных тел (спрайтов). Вы научитесь комбинировать глобальные и локальные настройки, чтобы создавать разнообразные физические эффекты — от классического падения до антигравитации — с помощью всего нескольких строк кода.
Версия 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('block', 'assets/sprites/block.png');
}
create ()
{
const group = this.physics.add.group({
defaultKey: 'block',
bounceX: 1,
bounceY: 1,
collideWorldBounds: true
});
// World gravity
this.physics.world.gravity.y = 150;
// Total gravity is 150.
group.create(250, 300);
// Total gravity is 450.
group.create(350, 300).setGravity(0, 300);
// Total gravity is 150.
group.create(450, 300).setGravity(0, -300);
// No gravity.
group.create(550, 300, 'block').body.setAllowGravity(false);
}
}
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);
Настройка мировой гравитации
В Arcade Physics гравитация может быть задана для всего физического мира. Это базовый уровень, влияющий на все тела, у которых не отключена гравитация явно. Гравитация задается через свойство gravity объекта this.physics.world.
// Устанавливаем вертикальную гравитацию для всего мира.
// Положительное значение тянет объекты вниз.
this.physics.world.gravity.y = 150;
После этой настройки все физические тела в сцене будут подвержены силе тяжести, тянущей их вниз со скоростью 150 пикселей в секунду в квадрате (px/s²). Это значение можно менять динамически во время выполнения игры.
Создание физической группы
Для удобной работы с множеством однотипных объектов используется физическая группа (Physics Group). Она позволяет задать общие свойства для всех создаваемых в ней тел.
const group = this.physics.add.group({
defaultKey: 'block', // Текстура по умолчанию
bounceX: 1, // Идеальный отскок по оси X (без потерь энергии)
bounceY: 1, // Идеальный отскок по оси Y
collideWorldBounds: true // Столкновение с границами мира
});
Группа создается с помощью метода this.physics.add.group(). Параметр defaultKey указывает ключ текстуры, которая будет автоматически использоваться для новых спрайтов в группе. Свойства bounceX и bounceY определяют упругость объектов, а collideWorldBounds включает столкновение с краями игрового поля.
Индивидуальная гравитация для тел
Сила гравитации для отдельного тела задается методом setGravity(). Эта гравитация добавляется к мировой. Если мировая гравитация равна 150, а для тела установлена своя гравитация 300, то общая сила, действующая на тело, составит 450.
// Создаем спрайт в группе. На него действует только мировая гравитация (150).
group.create(250, 300);
// Создаем спрайт и задаем ему дополнительную гравитацию.
// Общая гравитация: мировая (150) + индивидуальная (300) = 450.
group.create(350, 300).setGravity(0, 300);
// Можно задать отрицательное значение, чтобы тянуть объект вверх.
// Общая гравитация: 150 + (-300) = -150 (объект летит вверх).
group.create(450, 300).setGravity(0, -300);
Метод setGravity() принимает два аргумента: гравитацию по оси X и по оси Y. В нашем примере изменяется только вертикальная составляющая.
Полное отключение гравитации
Иногда объект не должен подвергаться воздействию гравитации. Например, это может быть платформа, парящая в воздухе, или объект, управляемый игроком. Для этого у физического тела (body) нужно установить свойство allowGravity в false.
// Создаем спрайт и получаем доступ к его физическому телу.
// Метод setAllowGravity(false) полностью отключает гравитацию для этого тела.
group.create(550, 300, 'block').body.setAllowGravity(false);
Обратите внимание: чтобы отключить гравитацию, нужно обратиться к свойству .body созданного спрайта. Метод setAllowGravity(false) гарантирует, что ни мировая, ни индивидуальная гравитация на этот объект действовать не будут.
Что попробовать дальше
Гравитация в Phaser Arcade Physics — это многоуровневая система. Вы можете задать общие правила для всей сцены через this.physics.world.gravity, а затем тонко настраивать поведение отдельных объектов с помощью setGravity() или полностью отключать его через setAllowGravity(). Для экспериментов попробуйте:
1. Динамически менять мировую гравитацию по таймеру или событию.
2. Создать область с "аномальной" гравитацией, где объекты притягиваются в сторону.
3. Реализовать прыжок персонажа, временно отключая для него гравитацию и задавая вертикальную скорость.
