Box2D Как повернуть колесо вокруг оси, потянув за один из его краев?

Я новичок в Box2D (в данном случае JBox2d), и я создаю меню колеса в приложении для Android. Я хочу, чтобы пользователь мог выбрать один пункт меню, и колесо должно автоматически поворачиваться в нужный раздел. Тело колеса является динамическим, прикрепленным вращательным соединением в его центре к якорю (статическому). Я использую дистанционное соединение между местом касания пользователя внутри моего колеса и статическим телом, расположенным сверху моего колеса. Нажмите на раздел с именем TA_Multilist

У меня проблема с настройками косяка. Я не могу понять комбинацию длины/демпфирования/частоты, поэтому я могу получить быструю тягу с минимальными колебаниями в конце. Кроме того, если я выберу один из элементов на верхней стороне колеса, они остановятся в нужном месте. Но если я нажму один в конце, соединение не будет учитывать длину 0, которую я ему дал, и я получаю это: Смещенное колесо

Если я использую длину 0, коэффициент демпфирования 1 и частоту Гц 0, результат будет идеальным, но у меня нет анимации: она мгновенно переходит в нужное положение.

В iOS я сделал то же самое меню, используя UIKit Dynamics, и получил отличный результат: https://www.dropbox.com/s/mb2i44geinw9yp6/iOS_wheel_rotation.mov?dl=0

Заранее спасибо за любое руководство.


person mbritto    schedule 18.12.2014    source источник


Ответы (1)


Я думаю, что основная проблема заключается в типе сустава, который вы пытаетесь использовать.

Distance Joint предполагает, что расстояние между двумя соединяемыми точками является постоянным (базовые предположения о соединениях box2d в целом могут немного изменить это правило, но все же...).

Попробуйте использовать MouseJoint и просто помните:

  • Когда вы создаете MouseJoint и прикрепляете его к телу (точно так же, когда вы создаете MouseJointDef), вы указываете target, который в этот конкретный момент (И ТОЛЬКО ТОГДА) означает часть тела, в которой вы хотите заякориться. MouseJoint (указывая еще раз - это внутри этого тела!). Так что в вашем случае это target должно указывать на затронутую часть вашего колеса.

  • Когда вы закончите создание соединения (то есть после того, как вы вызвали <World_Object>.createJoint(<your_joint>)), target указывает место, куда вы хотите переместить ранее установленное target (внутри этого тела) (так что этот якорь в верхней части колеса).

Таким образом, в основном вы должны создать соединение мыши при касании с кодом, подобным этому:

MouseJoint wheelJoint;
MouseJointDef mouseJointDef = new MouseJointDef();
mouseJointDef.bodyA = <something>;
mouseJointDef.bodyB = wheelBody;
mouseJointDef.target.set(0 + chosenWheelPositionOffsetX, 0 + chosenWheelPositionOffsetY);
mouseJointDef.target.addLocal(wheelCenterX, wheelCenterY);
mouseJointDef.dampingRatio = <chosen_value>;
mouseJointDef.frequencyHz = <chosen_value>;
mouseJointDef.maxForce = <chosen_value>;
wheelJoint = (MouseJoint) mWorld.createJoint(mouseJointDef);

и после этого вы должны позвонить

wheelJoint.setTarget(topAnchorX, topAnchorY);

Настройте <chosen_value>s так, чтобы ваше представление работало точно так, как задумано.

Надеюсь, все понятно, дайте знать, если что-то не так. Также, пожалуйста, дайте мне знать, если изменение типа соединения поможет решить ваши проблемы.

person Bartek Lipinski    schedule 19.12.2014
comment
Спасибо за ваш подробный ответ. Я не могу заставить его работать, хотя. Есть ли какое-либо конкретное ограничение для поддельного тела A? Странно то, что ничего не происходит, когда я его использую, и ничего не рисуется в моем представлении отладки, которое обычно рисует розовые тела и суставы. - person mbritto; 19.12.2014
comment
Наконец-то я получил то, что начинает работать. Вы были правы насчет использования MouseJoint, это определенно правильный путь. Я вернусь с правильными значениями силы/демпфирования/частоты, как только найду их. - person mbritto; 19.12.2014
comment
К вашему сведению, вот значения, которые я использовал для своего 1-метрового круга: частота: 1, демпфирование: 0,3 и maxForce: 10. Еще раз спасибо за помощь. - person mbritto; 15.01.2015