О чем этот пример
Когда вам нужно создать сложный игровой объект из нескольких спрайтов, который при этом должен подчиняться законам физики, простого добавления физического тела к каждому спрайту недостаточно. 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('platform', 'assets/sprites/platform.png');
this.load.image('mushroom', 'assets/sprites/mushroom2.png');
}
create ()
{
const image1 = this.add.image(0, -30, 'mushroom');
const image2 = this.add.image(-40, 30, 'mushroom');
const image3 = this.add.image(40, 30, 'mushroom');
const container = this.add.container(100, 100, [ image1, image2, image3 ]);
// A Container has a default size of 0x0, so we need to give it a size before enabling a physics body
container.setSize(128, 64);
const physicsContainer = this.matter.add.gameObject(container);
physicsContainer.setFrictionAir(0.001);
physicsContainer.setBounce(0.9);
this.matter.add.image(350, 450, 'platform', null, { isStatic: true }).setScale(2, 0.5).setAngle(10);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#1b1464',
parent: 'phaser-example',
physics: {
default: 'matter',
matter: {
debug: true,
gravity: {
y: 0.3
}
}
},
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и загрузка ассетов
Класс сцены наследуется от Phaser.Scene. В методе preload задаётся базовый URL для загрузки ресурсов и загружаются два изображения: спрайт гриба и платформы.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('platform', 'assets/sprites/platform.png');
this.load.image('mushroom', 'assets/sprites/mushroom2.png');
}
Создание контейнера и его содержимого
В методе create создаются три отдельных изображения гриба. Координаты (0, -30), (-40, 30) и (40, 30) задаются относительно будущей позиции контейнера. Затем эти изображения добавляются в контейнер.
const image1 = this.add.image(0, -30, 'mushroom');
const image2 = this.add.image(-40, 30, 'mushroom');
const image3 = this.add.image(40, 30, 'mushroom');
const container = this.add.container(100, 100, [ image1, image2, image3 ]);
Контейнер изначально имеет нулевой размер, что непригодно для физики. Поэтому перед созданием тела необходимо явно задать его размеры с помощью метода setSize. В данном случае задаётся прямоугольная область 128x64 пикселя, которая будет коллайдером для физического тела.
container.setSize(128, 64);
Добавление физики Matter к контейнеру
Ключевой шаг — превращение обычного контейнера в физический объект системы Matter. Это делает метод this.matter.add.gameObject(). Он принимает игровой объект (в нашем случае контейнер) и добавляет к нему компоненты физического тела.
const physicsContainer = this.matter.add.gameObject(container);
После этого к объекту physicsContainer можно применять методы физики Matter, такие как setFrictionAir для задания сопротивления воздуха и setBounce для коэффициента отскока.
physicsContainer.setFrictionAir(0.001);
physicsContainer.setBounce(0.9);
Создание статической платформы
Чтобы составной объект мог с чем-то взаимодействовать, создаётся статическая платформа. Она не будет двигаться под действием сил. Метод this.matter.add.image создаёт изображение с физическим телом Matter. Параметр { isStatic: true } делает тело статическим. После создания платформа масштабируется и поворачивается.
this.matter.add.image(350, 450, 'platform', null, { isStatic: true }).setScale(2, 0.5).setAngle(10);
Конфигурация игры и физики Matter
Конфигурационный объект игры включает настройки физического движка Matter. Важно установить default: 'matter' в разделе physics. В подразделе matter включается отладка (debug: true), чтобы видеть контуры тел, и задаётся слабая гравитация по оси Y.
physics: {
default: 'matter',
matter: {
debug: true,
gravity: {
y: 0.3
}
}
}
Что попробовать дальше
Использование контейнеров как единых физических тел — мощный приём для моделирования сложных игровых объектов. Вы можете экспериментировать: создавать контейнеры из анимированных спрайтов, менять форму и размер коллайдера с помощью setBody, объединять несколько физических контейнеров с помощью шарниров (constraint) для создания, например, движущейся гусеницы или манипулятора.
