Bodies can be moved in two ways by using mouse joint or setPosition. The difference between using mouse joint and setPosition function is that if body is moved by setPosition function, it does not interact with other objects in the world. On the other hand, if body is moved using mouse joint, it interacts with other objects according to physical laws.
Box 2D coordinates
Mouse joint does not use normal screen pixel coordinates, usually used in drawing functions or in other Moscrif classes and functions. Box2d uses its own coordinates. It uses meters as units for distance. The screen width is set to represent a distance of 10 meters. The world has property scale, which determines how many pixels are in one meter.
E.g.: On iPhone 4 retina display (640x960px), Scale property is 64 (which means that one meter is 64 pixels in the screen). If we create circle with radius 50px, it behaves like a real circle with radius of about 78 centimeters.
Zero points of box2D coordinates are in bottom-left corner.
Image: box2D coordinates

How to create mouse joint?
Mouse joint is represented by MouseJoint class. However, this class has no constructor, which means that instance of this class has to be created by createMouseJoint function. First two parameters are instances of physical bodies. First body is officially ground body, but it does not have to have specific settings. We use body with zero height and width placed in top-left corner. Second body is a body connected with a mouse joint. The createMouseJoint function also uses some additional options - set in JSON object in the third parameter. These additional options are:
-
targetX: X coordinate of anchor point on the body, which may be connected in the joint
-
targetX: Y coordinate of anchor point on the body, which may be connected in the joint
-
maxForce: maximum force, which attracts the body to the target point
-
frequencyHz: affects the speed and accuracy of the joint
-
dampingRatio: prevents oscillation of the body around the target point
We created mouse joint in pointer pressed function, which is called when the user taps on the screen.
Example: create mouse joint (the beginning of pointerPressed function)
// reaction to pointer pressed event
function pointerPressed(x, y)
{
// get position of circle
var (cx, cy) = this._circle.getPosition();
//set mouse joint
var mouseJointDef = {
maxForce : 350 * this._circle.getMass(), // max force, which attracts the body to the target point
frequencyHz : 100,
dampingRatio : 15.0, // damping ratio - prevent oscillation of the body around the target point
targetX : cx / this.scale, // X position of anchor point on the body (circle)
targetY : (System.height - cy) / this.scale // Y position of anchor point on the body (circle) };
// crate mouse joint
this._mouseJoint = this.createMouseJoint(this._ground, this._circle, mouseJointDef, true);
...
Body moving
When we created a mouse joint with body, it does not mean that the body will move automatically. We need to use function setTarget in pointer events. In pointer pressed event, we use setTarget function. Using this function causes that when the user taps onto the screen, the body moves to the finger position.
Example: move body to pointer position (the end of pointerPressed function)
...
if (this._mouseJoint != null) {
// calculate target points (current pointer position)
var b2y = (System.height-y) / this.scale;
var b2x = x / this.scale;
// set target
this._mouseJoint.setTarget(b2x, b2y);
}
}
Body dragging
We can also use setTarget in pointerDragged event and the body will move according to the finger movement.
Example: body dragging
// reaction to pointer dragged event
function pointerDragged(x, y)
{
// if mouse joint exists
if (this._mouseJoint != null) {
// calculate target point
var b2y = (System.height-y) / this.scale;
var b2x = x / this.scale;
// set target
this._mouseJoint.setTarget(b2x, b2y);
}
}
Clean up
When pointer is released joint should be destroy and reset mouse joint variable. This ensures that when the user taps on the screen next time, new mouse joint will be created correctly.
Example: clean up
// reaction to pointer released event
function pointerReleased(x, y)
{
// if mouse joint exists destroy it
if (this._mouseJoint != null) {
this.destroyJoint(this._mouseJoint);
this._mouseJoint = null;
}
}
Summary
Mouse joint is a strong feature to move bodies according to finger movement. We create mouse joint using createMouseJoint function. To ensure movement, we use setTarget function to move body to required position in pointerPressed / Dragged or Released events. You also need to keep in mind that mouse joint uses box2d coordinates not screen pixel coordinates.
|