Box2D joints: Revolute Joint

Revolute joint дословно переводится как «вращательное соединение», и на самом деле, оно предназначено чтобы тела могли вращаться вокруг точки соединения.

С помощью этого соединения можно создавать цепи и верёвки в играх, а так же объекты, которые могут вращаться сами при помощи особенного свойства вращательных соединений — мотора.

Для примера я реализую следующие объекты:

  • простой прямоугольник прикреплённый к мировому телу, таким образом он будет вращаться как бы в воздухе;
  • 2 обычных объекта (квадрата) с точкой крепления вне своих фигур;
  • молот, который будет бить в землю под действием моторной силы и будет прикреплён к миру;
  • а так же цепь или верёвку (смотря что будет отображаться графикой в вашей игре — физическая суть одинакова).

Управление: P — скрыть\показать профайлер, R — пересоздать сцену, LMB — можно таскать предметы мышью.

Полный код примера

Создание всех объектов заключено в функции createObjs(). В данном примере главное новшество — это пределы углов соединения и мотор.

С пределами углов всё просто: указываем lowerAngle (минимальный угол) и upperAngle (максимальный угол), включаем эту логику выставлением enableLimit = true и угол между соединёнными телами находится в данных пределах.

А вот с мотором поинтереснее. Нужно настраивать 2 параметра — это maxMotorTorque (максимальный крутящий момент силы) и motorSpeed (угловая скорость мотора в рад/сек, которая достигается приложением крутящего момента в точке соединения). Чем больше момент, тем мощнее мотор и тем быстрее достигается указанная скорость мотора. Например, если указать момент = 500 или больше, а скорость = 1 (рад/сек), то тело практически моментально начнёт крутиться со скоростью 1 рад/с по часовой стрелке. А если указывать момент не большой, то тело будет крутиться с постепенным разгоном до указанной скорости. Далее необходимо включить мотор enableMotor = true и «оно задвигалось!».

Разнообразия ради я реализовал изменение скорости мотора, чтобы молот автоматически совершал удары. Вся логика изменения находится в функции update() в строках [461-470]. Один минус — если под молот положить например квадрат, то он стопорится. Всё потому что ожидается достижения предельного угла. Это легко решается, если смену направления силы сделать по таймеру, а не по достижению предельных углов.

Ну и пожалуй самый интересный объект, реализуемый данным соединением, — верёвка. Сначала я реализовал круглое основание и прикрепил его к мировому телу [244-250], затем прикрепил к нему первое звено как частный случай [253-258], а остальные звенья, т.к. они подобны, было легко создавать и прикреплять уже в цикле используя вспомогательную переменную prevBody, которая хранит ссылку на предыдущее звено [259-270].

На этом с данным соединением пожалуй всё, вопросы оставляйте в комментариях!

Скачать исходники