Физика 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 гораздо дороже Arcade в расчёте на одно тело. Самая значимая мера противодействия — засыпание: тела, которые какое-то время не двигались, временно исключаются из цикла интегрирования. Включите его в конфигурации (enableSleeping: true); осевшая стопка почти ничего не стоит, пока что-то её не потревожит.
Другие параметры:
positionIterationsиvelocityIterations— повышайте для более точных стопок ценой нагрузки на процессор. Значения по умолчанию 6/4 обычно подходят.- Количество тел. Matter масштабируется сублинейно, но не бесплатно. Несколько сотен активных тел комфортны на десктопе, ~50 — на мобильных устройствах среднего уровня.
- Не опрашивайте мир каждый кадр. Используйте события столкновений Matter (
'collisionstart','collisionactive','collisionend') вместо сканирования.
Интеграция со списком отображения
Игровые объекты Matter — это обычные игровые объекты Phaser: они находятся в списке отображения сцены, тонируются и анимируются как спрайты и могут быть вложены в контейнеры. Их позиция и поворот задаются физическим телом каждый кадр; прямая запись в .x/.y работает, но рассинхронизирует тело до следующего шага физики.
Связанные материалы
- Физика Arcade — более быстрый, менее выразительный собрат.
- Игровой цикл — как физический мир обсчитывается каждый кадр.