О чем этот пример
В игровой физике не все объекты должны подчиняться одним законам. Например, платформерам нужны летающие платформы, а в космических симуляторах — астероиды, не падающие на планеты. В этом примере показано, как в Phaser с плагином Matter.js отключить гравитацию для конкретных тел, оставив её воздействие на остальные объекты сцены. Этот приём даёт точный контроль над физическим поведением и позволяет создавать более разнообразные и интересные игровые механики.
Версия 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');
this.load.image('platform', 'assets/sprites/platform.png');
}
create ()
{
this.matter.world.setBounds();
// This body isn't effected by Gravity
this.matter.add.image(100, 100, 'block').setIgnoreGravity(true);
this.matter.add.image(300, 100, 'block', null, { restitution: 0.6, frictionAir: 0, mass: 0.1 });
this.matter.add.image(500, 100, 'block', null, { restitution: 0.8, frictionAir: 0, mass: 0.1 });
this.matter.add.image(700, 100, 'block', null, { restitution: 1, frictionAir: 0, mass: 0.1 });
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#1b1464',
parent: 'phaser-example',
physics: {
default: 'matter'
},
scene: Example
};
const game = new Phaser.Game(config);
Настройка физики Matter.js
Первым делом в конфигурации игры нужно активировать физический движок Matter.js. Это делается в объекте config, который передаётся конструктору Phaser.Game.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#1b1464',
parent: 'phaser-example',
physics: {
default: 'matter' // Активируем Matter.js как движок по умолчанию
},
scene: Example
};
Ключевой параметр — physics.default: 'matter'. Без него методы this.matter в сцене будут недоступны. Также важно, что в Matter.js для работы мировых границ (стен) нужно явно их создавать, в отличие от Arcade Physics.
Создание мира и статических платформ
В методе create() сцены инициализируется физический мир. Вызов this.matter.world.setBounds() создаёт непроходимые границы по краям игрового поля.
create ()
{
this.matter.world.setBounds();
// ... создание объектов
}
Метод setBounds() без аргументов использует размеры игрового мира, определённые в config. Это стандартный способ оградить игровое пространство. Внутри этих границ и будут взаимодействовать все физические тела.
Создание тела, игнорирующего гравитацию
В Matter.js каждое тело можно наделить уникальными свойствами. В примере первое тело создаётся так, чтобы на него не действовала сила тяжести.
this.matter.add.image(100, 100, 'block').setIgnoreGravity(true);
Метод this.matter.add.image() создаёт физическое тело на основе спрайта. Цепочка вызовов .setIgnoreGravity(true) применяется к только что созданному телу и устанавливает его свойство ignoreGravity в true. Это значит, что глобальная гравитация мира (по умолчанию направленная вниз) на это тело действовать не будет. Оно останется висеть в воздухе на той позиции, где было создано.
Сравнение с обычными физическими телами
Чтобы продемонстрировать разницу, в примере создаются ещё три блока, которые гравитации подчиняются. Они будут падать и отскакивать от нижней границы.
this.matter.add.image(300, 100, 'block', null, { restitution: 0.6, frictionAir: 0, mass: 0.1 });
this.matter.add.image(500, 100, 'block', null, { restitution: 0.8, frictionAir: 0, mass: 0.1 });
this.matter.add.image(700, 100, 'block', null, { restitution: 1, frictionAir: 0, mass: 0.1 });
Эти блоки создаются с дополнительными физическими параметрами, переданными пятым аргументом:
* restitution — упругость (от 0 до 1). Блок с restitution: 1 отскочит от земли почти без потерь энергии.
* frictionAir: 0 — отсутствие сопротивления воздуха, чтобы падение и отскоки были идеальными.
* mass: 0.1 — малая масса для более динамичного движения.
При запуске примера эти три блока упадут, а первый блок, созданный с setIgnoreGravity(true), останется на месте.
Что попробовать дальше
Метод setIgnoreGravity() — это мощный инструмент для тонкой настройки физики. Он позволяет нарушать общие правила для отдельных объектов, что открывает простор для дизайна уровней. Попробуйте поэкспериментировать: создайте платформу, которая парит в воздухе, или снаряд, летящий по прямой в невесомости. Можно комбинировать это свойство с другими, например, сделать тело не только невесомым, но и статичным (setStatic(true)), чтобы создать абсолютно неподвижную опору в воздухе.
