~2 мин чтения

Физика Matter

Полноценная симуляция твёрдых тел для укладки стопкой, соединений, составных тел и всего, что не может смоделировать Arcade.

Matter — это тяжеловесный вариант физики. Он моделирует настоящие твёрдые тела — с вращением, трением, упругостью, соединениями, ограничениями и произвольными полигональными формами — ценой большей нагрузки на процессор на одно тело и более сложного API.

Когда использовать Matter

Выбирайте Matter, как только вам понадобится что-либо из перечисленного:

  • Вращение. Наклонённый ящик, который приходит в состояние покоя на склоне под правильным углом.
  • Укладка стопкой. Куча ящиков, которая реалистично оседает.
  • Соединения / ограничения. Верёвки, цепи, шарниры, пружины, моторизованные колёса.
  • Составные тела. Транспортное средство с шасси плюс отдельными колёсами.
  • Полигональные столкновения. Непрямоугольная зона поражения.

Для всего остального предпочитайте Arcade — он на порядок быстрее.

Включение Matter

new Phaser.Game({
	physics: {
		default: 'matter',
		matter: {
			gravity: { y: 1 },           // масштаб гравитации Matter, а не пикселей/с^2
			debug: false,
			enableSleeping: true,        // прекращать интегрирование осевших тел
		},
	},
});

Внутри сцены this.matter — это мир.

Создание тел

// Прямоугольное тело — простейший случай.
const box = this.matter.add.image(200, 100, 'crate');

// Окружность.
const ball = this.matter.add.image(300, 100, 'ball', undefined, { shape: 'circle' });

// Полигон из явно заданных вершин.
const tri = this.matter.add.fromVertices(400, 100, '0 0 60 0 30 50', { friction: 0.4 });

// Составное тело — полезно, когда одному объекту нужно несколько отдельных зон поражения.
const ship = this.matter.add.image(500, 100, 'ship', undefined, {
	shape: { type: 'fromVerts', verts: shipHullPath, flagInternal: true },
});

Типичные свойства, задаваемые для каждого тела:

box.setStatic(false);
box.setFriction(0.3, 0.001, 0.05);   // поверхностное, воздушное, статическое
box.setBounce(0.4);
box.setMass(2);
box.setAngularVelocity(0.05);

Ограничения и соединения

// Маятник — статический якорь с качающимся грузом.
// Якорям не нужна текстура; достаточно небольшого невидимого прямоугольного тела.
const anchor = this.matter.add.rectangle(400, 50, 4, 4, { isStatic: true });
const weight = this.matter.add.image(400, 200, 'weight');
this.matter.add.constraint(anchor, weight, 150, 0.9);

// Верёвка из N сегментов.
let prev = anchor;
for (let i = 0; i < 10; i++) {
	const segment = this.matter.add.image(400 + i * 10, 80, 'link');
	this.matter.add.constraint(prev, segment, 12, 0.9);
	prev = segment;
}

constraint(a, b, length, stiffness)stiffness: 1 — это жёсткий стержень, stiffness: 0.001 — мягкая пружина.

Живой пример

Небольшая стопка ящиков оседает на полу.

Matter stacking Phaser 4 · sandboxed

Производительность: засыпание

Matter гораздо дороже Arcade в расчёте на одно тело. Самая значимая мера противодействия — засыпание: тела, которые какое-то время не двигались, временно исключаются из цикла интегрирования. Включите его в конфигурации (enableSleeping: true); осевшая стопка почти ничего не стоит, пока что-то её не потревожит.

Другие параметры:

  • positionIterations и velocityIterations — повышайте для более точных стопок ценой нагрузки на процессор. Значения по умолчанию 6/4 обычно подходят.
  • Количество тел. Matter масштабируется сублинейно, но не бесплатно. Несколько сотен активных тел комфортны на десктопе, ~50 — на мобильных устройствах среднего уровня.
  • Не опрашивайте мир каждый кадр. Используйте события столкновений Matter ('collisionstart', 'collisionactive', 'collisionend') вместо сканирования.

Интеграция со списком отображения

Игровые объекты Matter — это обычные игровые объекты Phaser: они находятся в списке отображения сцены, тонируются и анимируются как спрайты и могут быть вложены в контейнеры. Их позиция и поворот задаются физическим телом каждый кадр; прямая запись в .x/.y работает, но рассинхронизирует тело до следующего шага физики.

Связанные материалы

  • Физика Arcade — более быстрый, менее выразительный собрат.
  • Игровой цикл — как физический мир обсчитывается каждый кадр.