О чем этот пример
Phaser в паре с физическим движком Matter.js открывает возможности для создания сложных объектов нестандартной формы, которые могут сталкиваться и взаимодействовать по законам физики. В игровой механике это полезно для проектирования уникальных препятствий, врагов, разрушаемых объектов или интерактивных элементов интерфейса. Эта статья покажет, как превратить простые полигоны в полноценные физические тела, используя вершинное описание формы.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
this.matter.world.setBounds().disableGravity();
const arrow = '40 0 40 20 100 20 100 80 40 80 40 100 0 50';
const chevron = '100 0 75 50 100 100 25 100 0 50 25 0';
const star = '50 0 63 38 100 38 69 59 82 100 50 75 18 100 31 59 0 38 37 38';
{
const poly = this.add.polygon(400, 300, arrow, 0x0000ff, 0.2);
this.matter.add.gameObject(poly, { shape: { type: 'fromVerts', verts: arrow, flagInternal: true } });
poly.setVelocity(6, 3);
poly.setAngularVelocity(0.01);
poly.setBounce(1);
poly.setFriction(0, 0, 0);
}
{
const poly = this.add.polygon(400, 100, chevron, 0xff0000, 0.2);
this.matter.add.gameObject(poly, { shape: { type: 'fromVerts', verts: chevron, flagInternal: true } });
poly.setVelocity(6, 3);
poly.setAngularVelocity(0.01);
poly.setBounce(1);
poly.setFriction(0, 0, 0);
}
{
const poly = this.add.polygon(600, 400, star, 0x00ff00, 0.2);
this.matter.add.gameObject(poly, { shape: { type: 'fromVerts', verts: star, flagInternal: true } });
poly.setVelocity(4, -2);
poly.setBounce(1);
poly.setFriction(0, 0, 0);
poly.setFrictionAir(0.005);
}
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#efefef',
parent: 'phaser-example',
physics: {
default: 'matter',
matter: {
debug: true
}
},
scene: Example
};
const game = new Phaser.Game(config);
Настройка сцены и физики
Перед созданием объектов необходимо настроить сцену и физический движок. В методе create() мы отключаем гравитацию для полного контроля над движением тел и устанавливаем границы мира, чтобы объекты не вылетали за пределы области видимости.
this.matter.world.setBounds().disableGravity();
Конфигурация игры указывает на использование Matter.js в качестве основного физического движка. Параметр debug: true включает отладочную визуализацию, которая рисует контуры физических тел — это крайне полезно при разработке.
Описание формы через вершины
Phaser позволяет описывать полигон через строку координат. Каждая пара чисел — это X и Y вершины относительно центра полигона. Такой формат удобен для задания сложных форм.
const arrow = '40 0 40 20 100 20 100 80 40 80 40 100 0 50';
const chevron = '100 0 75 50 100 100 25 100 0 50 25 0';
const star = '50 0 63 38 100 38 69 59 82 100 50 75 18 100 31 59 0 38 37 38';
Здесь мы определяем три разные фигуры: стрелку, шеврон и звезду. Эти строки используются как для графического отображения, так и для построения физического коллайдера.
Создание графического полигона
Сначала создаётся визуальный объект — полигон. Метод this.add.polygon() принимает координаты центра, строку с вершинами, цвет заливки и её альфа-канал (прозрачность).
const poly = this.add.polygon(400, 300, arrow, 0x0000ff, 0.2);
Это создаёт синюю полупрозрачную стрелку в центре экрана. На данном этапе это просто изображение без физических свойств.
Применение физического тела
Ключевой шаг — добавление к графическому объекту физического тела с помощью this.matter.add.gameObject(). В конфигурации указывается, что форма тела (shape) должна быть создана из вершин (type: 'fromVerts'). Параметр flagInternal: true помогает движку корректно обрабатывать вогнутые формы.
this.matter.add.gameObject(poly, { shape: { type: 'fromVerts', verts: arrow, flagInternal: true } });
После этого вызова объект poly становится полноценным телом Matter.js и наследует все его методы, такие как setVelocity или setBounce.
Настройка физических свойств
Теперь можно задать тело начальную скорость, вращение, упругость и трение. Эти свойства определяют поведение объекта при движении и столкновениях.
poly.setVelocity(6, 3);
poly.setAngularVelocity(0.01);
poly.setBounce(1);
poly.setFriction(0, 0, 0);
setBounce(1) делает отскок абсолютно упругим, а setFriction(0, 0, 0) убирает трение о поверхности и воздух. Для зелёной звезды дополнительно задано небольшое аэродинамическое сопротивление через setFrictionAir(0.005), что постепенно замедляет её.
Что попробовать дальше
Сочетание add.polygon и matter.add.gameObject позволяет легко создавать сложные интерактивные объекты с физикой. Для экспериментов попробуйте: изменить координаты вершин, чтобы создать собственную неправильную форму; комбинировать несколько полигонов в составное тело; использовать сенсоры (isSensor: true) для создания триггерных зон сложной формы; анимировать изменение вершин уже движущегося тела для эффекта трансформации.
