サイトのトップへ戻る

AndEngineドキュメント 日本語訳

回転Joint:

前回の記事では、jointについての基本的な情報について紹介しました。 we briefly mentioned what Revolute joint is: it forces two bodies to share a common anchor point, often called a hinge point. The revolute joint has a single degree of freedom: the relative rotation of the two bodies. This is called the joint angle. Before reading make sure you read introduction, and use same version of engines! 
Click Here to read joints introduction.

Have a look on the image posted below, showing example of revolute joint in practise (image from BOX2D Manual page) showing two bodies connected with revolute joint:

Picture


1. Revolute joint example:
Lets say we want to achieve following effect, like on the GIF posted below (please note that  box2d debug has been enabled in this example, so you can see body shape outlines, and anchor center of the joint, which is super useful while developing advanced things)
Picture
So to clarify, we have two bodies, dynamic one for moving arm (red rectangle) and static body for not moving green rectangle. Those two bodies are connected by revolute joint, with anchor center in the middle of the green rectangle. This kind of the joint, also lets us to enable motor so it can move like on this GIF above. We can adjust motor speed (and direction) and maximum motor torque. That`s how I achieved that:

// Create green rectangle
final Rectangle greenRectangle = new Rectangle(400, 240, 40, 40, getVertexBufferObjectManager());
greenRectangle.setColor(Color.GREEN);
scene.attachChild(greenRectangle);

// Create red rectangle
final Rectangle redRectangle = new Rectangle(460, 240, 120, 10, getVertexBufferObjectManager());
redRectangle.setColor(Color.RED);
scene.attachChild(redRectangle);

// Create body for green rectangle (Static)
final Body greenBody = PhysicsFactory.createBoxBody(physicsWorld, greenRectangle, BodyType.StaticBody, PhysicsFactory.createFixtureDef(0, 0, 0));

// Create body for red rectangle (Dynamic, for our arm)
final Body redBody = PhysicsFactory.createBoxBody(physicsWorld, redRectangle, BodyType.DynamicBody, PhysicsFactory.createFixtureDef(5, 0.5f, 0.5f));
physicsWorld.registerPhysicsConnector(new PhysicsConnector(redRectangle, redBody, true, true));

// Create revolute joint, connecting those two bodies 
final RevoluteJointDef revoluteJointDef = new RevoluteJointDef();
revoluteJointDef.initialize(greenBody, redBody, greenBody.getWorldCenter());
revoluteJointDef.enableMotor = true;
revoluteJointDef.motorSpeed = -1;
revoluteJointDef.maxMotorTorque = 100;
physicsWorld.createJoint(revoluteJointDef);

// Attach box2d debug renderer if you want to see debug.
scene.attachChild(new DebugRenderer(physicsWorld, getVertexBufferObjectManager()));
  1. Created first rectangle (green one) and set proper colour for it.
  2. Created red rectangle, set colour, positioned it in the proper position 
  3. Created body both for green rectangle (Static) and for red one (Dynamic)
  4. Registered physics connector for the red body, since its dynamic, we need to keep sprite`s position updated (sprite will follow body position)
  5. Created joint revolute joint definition, using initialize method we initialized our joint (providing parameters, first body, second body, and the anchor center of the joint, which in our example is in the middle of the green rectangle)
  6. Attached box2d debug renderer (read joints introduction for more info!)
Important note: while setting position of the physics element, such as body position, or position of the anchor of the joint, always remember about using proper unit, you need meters, not pixels (to receive desired effect) To convert pixels to meters, you can do the following trick

float pixelsInMeters = pixelsValue / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;


2. Frequently asked questions:
Question: How to change direction of the motor movement?
While creating revolute joint definition, and setting motorSpeed value , simply multiply your value by -1 (in other words, change the sign of your value) 
Questions: What is maximum motor torque value?
The maximum motor torque used to achieve the desired motor speed, if for instance, in our example, we would use much lower value (ex. 50 instead of 100) - motor torque would be to weak to perform full 360 degrees rotation.
Question: How to adjust joint values after creation, on the runtime?
People often are making silly mistake, keeping reference to the RevoluteJointDef (joint definition) and than changing its values, expecting to result in any change, but it will not change anything, because its only a definition used to build Joint. To do it properly, we need to keep reference for our joint, just like that:
// Our reference
private RevoluteJoint revoluteJoint;

// While creating joint
revoluteJoint = (RevoluteJoint) physicsWorld.createJoint(revoluteJointDef);

By doing that, we are free to modify our joint latter on, ex. changing motor speed.