Статьи

Начало работы с Matter.js: модуль Body

В предыдущем уроке из этой серии вы узнали о модулях World и Engine в Matter.js. Методы, доступные в этих двух модулях, предназначены для управления поведением нескольких тел или всего мира одновременно. Тем не менее, в какой-то момент вам необходимо будет контролировать свойства отдельных тел в вашем мире.

Например, вы можете применить некоторую силу к определенному объекту или изменить его коэффициент трения. В таких случаях модуль Body в Matter.js может оказать большую помощь. Этот модуль содержит множество методов и свойств, позволяющих указывать значения для всех видов физических атрибутов, от массы до коэффициента восстановления. В этом уроке вы узнаете обо всех этих методах и свойствах и о том, как правильно их использовать.

Вы можете вращать любое твердое тело в мире Matter.js, используя метод rotate(body, rotation) . Вращение относительно текущего угла тела, и оно не сообщит ему никакой угловой скорости. Угол поворота указан в радианах.

Вы также можете масштабировать тело, используя метод scale(body, scaleX, scaleY, [point]) . Параметры scaleX и scaleY определяют величину масштабирования в горизонтальном и вертикальном направлениях соответственно. Имейте в виду, что любое такое масштабирование также обновит физические свойства тела, такие как его масса, площадь и инерция. Четвертый параметр указывает точку, вокруг которой происходит масштабирование. Если значение не указано, предполагается, что значением по умолчанию для точки масштабирования является центр тела.

Можно переместить тело по заданному вектору относительно его текущего положения, используя метод translate(body, translation) . Параметр перевода указывает новую позицию объекта относительно его текущей позиции. Вот часть кода из демонстрации, которая масштабирует, вращает и перемещает блок.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
var Body = Matter.Body;
var box = Bodies.rectangle(460, 120, 40, 40);
 
$(‘.scale’).on(‘click’, function () {
    Body.scale( box, 1.5, 1.2);
});
 
$(‘.rotate’).on(‘click’, function () {
    Body.rotate( box, Math.PI/6);
});
 
$(‘.translate’).on(‘click’, function () {
    Body.translate( box, {x: -10, y: 20});
});

Вы также можете придать объекту линейную скорость, используя метод setVelocity(body, velocity) . Применение скорости таким образом не изменяет угол, приложенную силу или положение соответствующего объекта. Положение объекта или его угол, вероятно, изменится, но библиотека специально не устанавливает для них никакого значения. Их значения определяются другими силами, действующими на объект, такими как трение.

Как и линейная скорость, вы также можете изменить угловую скорость объекта, используя метод setAngularVelocity(body, velocity) . В этом случае положение, угол и сила, приложенные к объекту, также остаются неизменными.

Следует иметь в виду, что скорость — это вектор в setVelocity() и число в setAngularVelocity() .

1
2
3
4
5
6
7
$(‘.linear’).on(‘click’, function () {
    Body.setVelocity( box, {x: 10, y: -10});
});
 
$(‘.angular’).on(‘click’, function () {
    Body.setAngularVelocity( box, Math.PI/6);
});

Помимо придания скорости объектам, вы также можете применить к ним вектор силы. Метод applyForce(body, position, force) может использоваться для применения вектора force к телу из заданной position . Эта сила может или не может привести к приложению крутящего момента на данном теле.

Следующий код применяет силу прямо в центре тела. Вектор силы равен {x: 0, y: -0.05} . Это означает, что приложенное усилие будет чисто вертикальным и направленным вверх. Следует помнить, что вертикальные силы в восходящем направлении имеют отрицательный знак в Matter.js. Другая вещь, на которую стоит обратить внимание, это то, насколько мало число, определяющее вертикальную силу. Сама сила гравитации в Matter.js имеет значение всего 1.

Движение шара после приложения сил кажется естественным, пока этот шар не сталкивается ни с одной из стен или пола. Обычно, когда вещи сталкиваются с чем-то, мы ожидаем, что они придут в норму. Энергия, с которой объект отскакивает, определяется коэффициентом восстановления.

В Matter.js его значение по умолчанию установлено равным нулю. Это означает, что любой объект, для которого реституция установлена ​​на ноль и сталкивается с чем-то другим, вообще не отскочит назад. Значение 1 будет означать, что объект отскочит назад с кинетической энергией, равной тому, что он имел до столкновения. Значение типа 0,5 означает, что объект отскочит назад только с 50% его предыдущей кинетической энергии. Значение восстановления для объекта можно контролировать с помощью ключа restitution .

В некоторых симуляциях вам может понадобиться изменить трение между разными телами. Это может быть достигнуто с помощью клавиш friction , frictionAir и frictionStatic .

  • Ключ friction определяет значение кинетического трения для тела. Он может иметь значение от 0 до 1. Значение 0 подразумевает, что тело может продолжать двигаться бесконечно, как только оно будет приведено в движение. Единственный способ остановить это — применить какую-то другую внешнюю силу. Окончательное значение трения между двумя объектами определяется по формуле Math.min(bodyA.friction, bodyB.friction) .
  • Ключ frictionStatic определяет значение трения, когда тело находится в покое. Значение по умолчанию для статического трения составляет 0,5. Более высокое значение означает, что для движения тела потребуется больше силы.
  • Клавиша FrictionAir используется для указания значения трения между телом и окружающим воздухом. Более высокое значение означает, что тело будет замедляться очень быстро при движении по воздуху. Влияние воздушного трения нелинейно.
01
02
03
04
05
06
07
08
09
10
11
$(‘.red-friction’).on(‘click’, function () {
  circleA.friction = 0.05;
  circleA.frictionAir = 0.0005;
  circleA.restitution = 0.9;
});
 
$(‘.res-friction’).on(‘click’, function () {
  circleA.friction = 0.1;
  circleA.frictionAir = 0.001;
  circleA.restitution = 0;
});

До этого момента мы не указывали цвет, ширину контура или стиль обводки для использования при рендеринге тела. Все эти свойства вложены в ключ render . Свойство fillStyle принимает строку для указания стиля заливки, отображающего тело. Свойство lineWidth принимает число, определяющее ширину линии, используемую при создании контура тела.

Нулевое значение означает, что ни одна строка не будет отображаться вообще. Свойство strokeStyle может использоваться для указания стиля обводки, используемого при визуализации контура тела. Вы можете вообще запретить рендеринг тела, установив visible ключ в false . Непрозрачность тела, которое вы хотите визуализировать, можно контролировать с помощью клавиши opacity .

Вы также можете использовать изображение вместо простых цветов и контуров для визуализации тела. Параметры для отображения тела с использованием спрайтов задаются с использованием другого набора свойств. Свойство texture определяет путь к изображению, которое должно использоваться в качестве текстуры спрайта.

xOffset и yOffset можно использовать для определения смещения по соответствующим осям спрайта. Аналогично, вы можете использовать свойства xScale и yScale чтобы определить масштабирование по оси x и y для спрайта. Вот некоторый код, который заменяет голубой фон нашего мяча футбольным спрайтом с сайта Open Game Art .

1
2
3
4
5
6
7
8
9
var ball = Bodies.circle(90, 280, 20, {
  render: {
    sprite: {
      texture: «path/to/soccer_ball.png»,
      xScale: 0.4,
      yScale: 0.4
    }
  }
});

Вы уже видели, как указать трение или коэффициент восстановления для объекта в Matter.js. Есть много других свойств, значения которых могут быть указаны таким же образом. С другой стороны, есть свойства, которые доступны только для чтения и не могут быть изменены вами.

Вы можете установить положение тела в мире, используя клавишу position , которая принимает вектор в качестве значения. Вы также можете указать массу тела, используя свойство mass , но затем вам также нужно будет установить значение для свойства inverseMass , которое рассчитывается с использованием 1/mass . Лучший способ контролировать массу тела — с помощью свойства density .

Как только вы измените плотность тела, его масса будет автоматически рассчитываться на основе его площади. Таким образом, вы также можете различать различные объекты в зависимости от их плотности. Например, тело, использующее камень в качестве спрайта, должно иметь более высокую плотность, чем тело того же размера, в котором в качестве спрайта используется футбольный мяч.

Некоторые свойства, такие как speed , velocity и angularVelocity , доступны только для чтения, но их значения можно установить с помощью соответствующих методов, таких как setAngularVelocity() и setVelocity() . Вы можете прочитать больше о различных свойствах модуля Body в документации .

В этом руководстве вы узнали обо всех важных методах и свойствах в модуле Body библиотеки Matter.js. Знание этих различных свойств и того, что они делают, может помочь вам создать более реалистичные симуляции реальной физики. В следующем и последнем руководстве серии вы узнаете о модуле Composite в Matter.js.

Если у вас есть какие-либо вопросы, связанные с этим руководством или советами по использованию библиотеки, поделитесь ими с нами.