Box2D joints: Distance Joint
One of the most interesting Box2D features are joints.
Joints are used to constraint two bodies together in various ways and allow you to create very complex objects such as ragdolls and motors.
At the moment, Box2D features six different joint types: Distance, Gear, Mouse, Prismatic, Pulley and Revolute joint.
In this post, we’ll learn everything about Distance joints.
A distance joint constrains two points on two bodies to remain at a fixed distance from each other.
You can think about it as a massless, rigid rod.
In this example we are going to create a square and a circle with a distance joint connecting them, all in just four lines.
Here they are:
And this is the source:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | package { import flash.display.Sprite; import flash.events.Event; import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*; import Box2D.Dynamics.Joints.*; import flash.events.MouseEvent; public class distance_joint extends Sprite { var mouseJoint:b2MouseJoint; var mousePVec:b2Vec2 = new b2Vec2(); var bd:b2BodyDef; var the_circle:b2CircleDef = new b2CircleDef(); var the_box:b2PolygonDef = new b2PolygonDef(); var the_joint:b2DistanceJointDef = new b2DistanceJointDef(); public function distance_joint() { // world setup var worldAABB:b2AABB = new b2AABB(); worldAABB.lowerBound.Set(-100.0, -100.0); worldAABB.upperBound.Set(100.0, 100.0); var gravity:b2Vec2=new b2Vec2(0.0,10.0); var doSleep:Boolean=true; m_world=new b2World(worldAABB,gravity,doSleep); // debug draw var m_sprite:Sprite; m_sprite = new Sprite(); addChild(m_sprite); var dbgDraw:b2DebugDraw = new b2DebugDraw(); var dbgSprite:Sprite = new Sprite(); m_sprite.addChild(dbgSprite); dbgDraw.m_sprite=m_sprite; dbgDraw.m_drawScale=30; dbgDraw.m_alpha = 1; dbgDraw.m_fillAlpha=0.5; dbgDraw.m_lineThickness=1; dbgDraw.m_drawFlags=b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit; m_world.SetDebugDraw(dbgDraw); // ground the_box.SetAsBox(9,0.5); the_box.density = 0; the_box.friction = 0.4; the_box.restitution = 0.1; bd = new b2BodyDef(); bd.position.Set(8.5, 13); var ground:b2Body = m_world.CreateBody(bd); ground.CreateShape(the_box); ground.SetMassFromShapes(); // circle the_circle.radius = 2; the_circle.density = 1.0; the_circle.friction = 0.4; the_circle.restitution = 0.3; bd = new b2BodyDef(); bd.position.Set(6, 2); var circle:b2Body = m_world.CreateBody(bd); circle.CreateShape(the_circle); circle.SetMassFromShapes(); // square the_box.SetAsBox(1.5,1.5); the_box.density = 1.0; the_box.friction = 0.4; the_box.restitution = 0.1; bd = new b2BodyDef(); bd.position.Set(2, 2); var box:b2Body = m_world.CreateBody(bd); box.CreateShape(the_box); box.SetMassFromShapes(); // joint the_joint.Initialize(circle, box, new b2Vec2(6,2),new b2Vec2(2,2)); the_joint.collideConnected = true; var joint:b2DistanceJoint = m_world.CreateJoint(the_joint)as b2DistanceJoint; // listeners stage.addEventListener(MouseEvent.MOUSE_DOWN, createMouse); stage.addEventListener(MouseEvent.MOUSE_UP, destroyMouse); addEventListener(Event.ENTER_FRAME, Update, false, 0, true); } public function createMouse(evt:MouseEvent):void { var body:b2Body=GetBodyAtMouse(); if (body) { var mouseJointDef:b2MouseJointDef=new b2MouseJointDef; mouseJointDef.body1=m_world.GetGroundBody(); mouseJointDef.body2=body; mouseJointDef.target.Set(mouseX/30, mouseY/30); mouseJointDef.maxForce=30000; mouseJointDef.timeStep=m_timeStep; mouseJoint=m_world.CreateJoint(mouseJointDef) as b2MouseJoint; } } public function destroyMouse(evt:MouseEvent):void { if (mouseJoint) { m_world.DestroyJoint(mouseJoint); mouseJoint=null; } } public function GetBodyAtMouse(includeStatic:Boolean=false):b2Body { var mouseXWorldPhys = (mouseX)/30; var mouseYWorldPhys = (mouseY)/30; mousePVec.Set(mouseXWorldPhys, mouseYWorldPhys); var aabb:b2AABB = new b2AABB(); aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001); aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001); var k_maxCount:int=10; var shapes:Array = new Array(); var count:int=m_world.Query(aabb,shapes,k_maxCount); var body:b2Body=null; for (var i:int = 0; i < count; ++i) { if (shapes[i].GetBody().IsStatic()==false||includeStatic) { var tShape:b2Shape=shapes[i] as b2Shape; var inside:Boolean=tShape.TestPoint(tShape.GetBody().GetXForm(),mousePVec); if (inside) { body=tShape.GetBody(); break; } } } return body; } public function Update(e:Event):void { m_world.Step(m_timeStep, m_iterations); if (mouseJoint) { var mouseXWorldPhys=mouseX/30; var mouseYWorldPhys=mouseY/30; var p2:b2Vec2=new b2Vec2(mouseXWorldPhys,mouseYWorldPhys); mouseJoint.SetTarget(p2); } } public var m_world:b2World; public var m_iterations:int=10; public var m_timeStep:Number=1.0/30.0; } } |
Let’s see what’s interesting in this script:
Line 16: Declaring the distance joint variable called the_joint
Line 70: Initializing the joint. The Initialize() method accepts four arguments: the first body affected by the joint, the second one, the point in the first body where to attach the joint and the point in the second one.
A little note: these points are absolute… if you look at them you will notice they have the same coordinates as circle origin (line 55) and box origin (line 65)… so when you are about to create a joint, you must know where are your objects
Line 71: when collideConnected is set to true, the bodies tied by the joint can collide each other. Otherwise they will overlap.
Line 72: Now it’s time to add the joint to the world.
The rest of the script is the yada yada already explained in other Box2D tutorials.
They can be easily customized to meet the unique requirements of your project.
8 Responses to “Box2D joints: Distance Joint”
Leave a Reply
Trackbacks
-
Box2D joints: Revolute Joint : Emanuele Feronato on
January 13th, 2009 5:34 pm
[...] introducing Distance Joints, it’s time to learn something about Revolute [...]
-
Box2D breakout prototype : Emanuele Feronato on
February 4th, 2009 2:27 pm
[...] bricks are hanging by distance joints attached to the body Ground, the paddle is fixed on the x axis by a prismatic joint attached also [...]
-
Creating a sling with Box2D using joints : Emanuele Feronato on
February 7th, 2009 10:43 pm
[...] used a distance joint, a revolute joint and a motor. The code does not need to be commented because there is nothing new, [...]
Posts
- Rick Triqui: my first PlayCrafter game
- Prototype of a Flash game like Meeblings
- Games for the game developers!
- The art of debugging
- How to embed a text file in Flash
- Create a Flash game in minutes with PlayCrafter
- Upgrade your Flash CS4 to 10.0.2
- Play Mazeroll, my latest Box2D game
- Triqui MochiAds Arcade plugin for WordPress Released!!
- The MochiAds funnel
- Flash game creation tutorial - part 1
- Create a Lightbox effect only with CSS - no javascript needed
- Flash game creation tutorial - part 2
- Make a Flash game like Flash Element Tower Defense - Part 2
- Flash game creation tutorial - part 3
- Create a flash draw game like Line Rider or others - part 1
- Create a Flash Racing Game Tutorial
- Make a Flash game like Flash Element Tower Defense - Part 1
- Create a flash artillery game - step 1
- Create a flash draw game like Line Rider or others - part 5
- Flash game creation tutorial – part 5.2




(4.9 out of 5) - Flash game creation tutorial – part 3




(4.86 out of 5) - Creation of a platform game with Flash – step 2




(4.84 out of 5) - Create a survival horror game in Flash tutorial – part 1




(4.82 out of 5) - Create a flash artillery game – step 1




(4.82 out of 5) - Create a Flash Racing Game Tutorial




(4.8 out of 5) - Create a flash artillery game – step 2




(4.75 out of 5) - New tile based platform engine – part 6 – ladders




(4.74 out of 5) - Flash game creation tutorial – part 2




(4.73 out of 5) - The experiment – one year later




(4.7 out of 5)


Nice!!! I love this!!! This’ll help me make a physics game, that’s for sure…
One question: Is it possible to make a “Leash type joint? (Like two dogs leashed together, if one is stationary, it can move ANYWHERE in the circle of movement, not just the circumference)
You should probably try putting lots of little joints together to make a rope (search the box2d forums for more info and known problems)
Oh and btw this is only blank when I put it in the same folder with box2dfolder, how to fix…?
Can you do a tut on the joints used in the cranks and pulleys example given please
In the initialization of the joint, you can use GetPosition() of the two bodies to get their current position (in the form of a b2Vec2), so you dont have to go look for them.
Thanks for these tutorials!