Аркадная физика
Физика из коробки
В курсе Canvas скорость, гравитацию, отскок и столкновения мы писали сами. В Phaser есть встроенная аркадная физика (Arcade Physics): простая и очень быстрая, её хватает для платформеров, шутеров, аркад. Включается в настройках игры:
new Phaser.Game({
// ...
physics: {
default: "arcade",
arcade: { gravity: { y: 0 }, debug: false }, // debug: true рисует рамки тел
},
scene: MainScene,
});
Тело
Чтобы физика управляла объектом, ему нужно тело (body):
create() {
this.ball = this.add.circle(200, 150, 12, 0xffd54f);
this.physics.add.existing(this.ball); // теперь у объекта есть this.ball.body
}
Дальше мы говорим не «сдвинь на столько-то пикселей», а «вот твоя скорость» — физика сама двигает
объект каждый кадр с учётом delta:
const body = this.ball.body;
body.setVelocity(150, -100); // пикселей в секунду по x и y
body.setVelocityX(0); // только по x
body.setCollideWorldBounds(true); // не вылетать за края мира
body.setBounce(1); // отскок: 1 — без потерь, 0.5 — теряет половину скорости
Для картинок есть ещё короче: this.physics.add.sprite(x, y, "hero") сразу создаёт спрайт с телом.
Гравитация
Гравитацию можно задать для всего мира (arcade.gravity.y в настройках) или отдельному телу:
this.player.body.setGravityY(600); // ускорение вниз, px/с²
Тело само будет ускоряться вниз — это та же формула vy += g × dt из курса Canvas.
Прыжок
Чтобы прыгать только с земли, у тела есть флаги, что под ним:
update() {
const body = this.player.body;
if (this.cursors.up.isDown && body.blocked.down) {
body.setVelocityY(-400);
}
}
body.blocked.down— упёрлось снизу в границу мира или статичный объект;body.touching.down— касается снизу другого тела;body.onFloor()— короткая проверка «стоит на земле».
Горизонтальное движение в платформере обычно задают скоростью, а не сдвигом: стрелка зажата —
setVelocityX(200), отпущена — setVelocityX(0).
Статичные тела и группы
Земля и платформы не должны падать от гравитации и сдвигаться от ударов. Для них есть статичные тела, а удобнее всего — статичная группа:
this.platforms = this.physics.add.staticGroup();
this.platforms.add(this.add.rectangle(200, 290, 400, 20, 0x795548)); // земля
this.platforms.add(this.add.rectangle(300, 200, 100, 20, 0x8d6e63)); // уступ
Группа — это набор объектов, с которым можно работать как с одним: проверять столкновения со всей
группой сразу, перебирать getChildren(), считать countActive().
Есть и обычные (динамические) группы — this.physics.add.group() — для монет, врагов, пуль: у них
тела двигаются.
collider — столкновения
Сами по себе тела проходят сквозь друг друга. Чтобы они сталкивались, добавляют collider:
this.physics.add.collider(this.player, this.platforms);
Теперь физика каждый кадр не даёт игроку войти в платформы: он стоит на них, упирается в стены,
бьётся головой о потолок. Collider работает между объектом, группой или массивами в любом
сочетании: collider(this.enemies, this.platforms) — враги тоже стоят на земле.
Отладка
Включи debug: true в настройках физики — Phaser нарисует рамку каждого тела и вектор скорости.
Это лучший способ понять, почему герой «проваливается» или застревает.
Итог
physics: { default: "arcade" }в настройках,this.physics.add.existing(obj)— тело объекту.- Тело:
setVelocity,setGravityY,setBounce,setCollideWorldBounds. - Прыжок —
setVelocityY(-N)только приbody.blocked.down. - Платформы —
staticGroup(); столкновения —this.physics.add.collider(a, b).