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, Damping : 0.3 และ maxForce : 10 ขอขอบคุณอีกครั้งสำหรับความช่วยเหลือ - person mbritto; 15.01.2015