Basic Box2D rope
It’s time to create a rope with Box2d.
To start defining a rope, we’ll start from something similar: a chain. A chain is a series of two or more connected links. The smaller and closer the links, the more flexible the chain. So we can define a rope as a “perfect chain”, with infinite links.
In a Box2D simulation, ropes as we know them aren’t possible. But we can construct chains, and according to the number of links they can approximate a rope quite well.
Obviously, the higher the number of links, the more accurate the simulation, the slowest and CPU intensive the simulation.
I found 10 links are a good compromise between simulation and performance.
Every link is (guess what?) linked to the previous one with a revolute joint. Refer to Box2D joints: Revolute Joint if you need more information about revolute joints.
The core of the whole script is the link variable. I simply “save” the reference of the last chain placed on the stage and create the joint between the last chain placed and the one I am going to place.
So I’m having the first link with a joint with the ceiling, the second one with a joint on the first one, the third with a joint on the second and so on.
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 133 134 135 136 137 138 139 140 141 142 143 144 | package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*; import Box2D.Dynamics.Joints.*; public class rope extends Sprite { var body:b2Body; public var m_world:b2World; public var m_iterations:int=10; public var m_timeStep:Number=1.0/30.0; var mouseJoint:b2MouseJoint; var mousePVec:b2Vec2 = new b2Vec2(); var bodyDef:b2BodyDef; var boxDef:b2PolygonDef; var circleDef:b2CircleDef; var revolute_joint:b2RevoluteJointDef=new b2RevoluteJointDef(); var link:b2Body; public function rope() { addEventListener(Event.ENTER_FRAME, Update, false, 0, true); stage.addEventListener(MouseEvent.MOUSE_DOWN, createMouse); stage.addEventListener(MouseEvent.MOUSE_UP, destroyMouse); 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 start 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; m_world.SetDebugDraw(dbgDraw); // ceiling bodyDef = new b2BodyDef(); bodyDef.position.x=8.5; bodyDef.position.y=0; boxDef = new b2PolygonDef(); boxDef.SetAsBox(2, 0.5); boxDef.density=0; boxDef.friction=0.5; boxDef.restitution=0.2; body=m_world.CreateBody(bodyDef); body.CreateShape(boxDef); link=body; // rope for (var i:int = 1; i <= 10; i++) { // rope segment bodyDef = new b2BodyDef(); bodyDef.position.x=8.5; bodyDef.position.y=i; boxDef = new b2PolygonDef(); boxDef.SetAsBox(0.1, 0.5); boxDef.density=100; boxDef.friction=0.5; boxDef.restitution=0.2; body=m_world.CreateBody(bodyDef); body.CreateShape(boxDef); // joint revolute_joint.Initialize(link, body, new b2Vec2(8.5, i-0.5)); m_world.CreateJoint(revolute_joint); body.SetMassFromShapes(); // saving the reference of the last placed link link=body; } // final body bodyDef.position.x=8.5; bodyDef.position.y=11; boxDef = new b2PolygonDef(); boxDef.SetAsBox(0.5,0.5); boxDef.density=2; boxDef.friction=0.5; boxDef.restitution=0.2; body=m_world.CreateBody(bodyDef); body.CreateShape(boxDef); revolute_joint.Initialize(link, body, new b2Vec2(8.5, 10.5)); m_world.CreateJoint(revolute_joint); body.SetMassFromShapes(); } 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); } } } } |
And this is the result:
Every object is draggable, except the ceiling.
Download the source code, Box2D library included, and enjoy.
They can be easily customized to meet the unique requirements of your project.
15 Responses to “Basic Box2D rope”
Leave a Reply
Trackbacks
-
iPhone Dev » Rope Simulate with Cocos2d and Box2d on
February 6th, 2010 5:46 am
[...] Rope Simulate with Cocos2d and Box2d February 5th, 2010 admin Leave a comment Go to comments This post presents a good idea on how to simulate a rope using the distance joint in Box2d . I re-implemented it using Cocos2d. If you have got problems, please refer to that post for more details or leave a comment. In addition, you can also find another way of simulating a rope using Box2d from here. [...]
- Citrus Engine released for free for learning
- My epic fail with ClickBank
- Get up to $100,000 for your next Flash game with Mochi GAME Developer Fund
- Create a dynamic content animated footer ad for your site in just 9 jQuery lines – 17 lines version
- Sell sitelocked version of your Flash games and even .fla sources to Free Online Games
- Protect your work from ActionScript code theft with SWF Protector
- Create a dynamic content animated footer ad for your site in just 9 jQuery lines
- Understanding Box2D’s one-way platforms, aka CLOUDS
- Triqui MochiAds Arcade plugin for WordPress upgraded to 1.2
- Box2D Flash game creation tutorial – part 2
- Create a Lightbox effect only with CSS - no javascript needed
- Flash game creation tutorial - part 1
- Create a Flash Racing Game Tutorial
- Flash game creation tutorial - part 2
- Make a Flash game like Flash Element Tower Defense - Part 2
- Flash game creation tutorial - part 3
- Triqui MochiAds Arcade plugin for WordPress official page
- Make a Flash game like Flash Element Tower Defense - Part 1
- Create a flash draw game like Line Rider or others - part 1
- Create a flash artillery game - step 1
- Flash game creation tutorial – part 5.2 (4.88/5)
- Create a flash artillery game – step 1 (4.79/5)
- Create a Flash Racing Game Tutorial (4.76/5)
- Create a survival horror game in Flash tutorial – part 1 (4.74/5)
- Create a flash artillery game – step 2 (4.74/5)
- Creation of a Flash arcade site using WordPress – step 2 (4.73/5)
- Flash game creation tutorial – part 1 (4.71/5)
- Flash game creation tutorial – part 2 (4.71/5)
- Create a flash draw game like Line Rider or others – part 1 (4.69/5)
- Creation of a platform game with Flash – step 2 (4.68/5)

(15 votes, average: 4.00 out of 5)



YOU ROCK!
how about the sweet old school game with the cup and the ball?
A ball is connected to the bottom of a cup, and you need to play with the cup till the ball get inside it… I dunno if you know what I mean, the game can be found in many variations.
Thanks!
-yarden
hell yeah, i like this rope :)
ergh…. sorry… but its look like a chain, not a rope… imho elastic nodes can help in simulation of rope
Surely it just needs more segments to be more convincing, maw? It certainly moves like rope.
Hay why don’t you make a tutorial for storing user data on their machine? That way the game remebers where they left off or their personal settings. Maybe even remember how they play and become harder. I heard its easy they are called Flash Cookies or something like that.
This, with elasticity, would be awesome.
The problem with this rope is when the box weights too much or you pull it too hard, the rope breaks down. Therefore you need to add distance joints. This was discussed on box2d forums looong time ago, see http://www.box2d.org/forum/viewtopic.php?p=10691#p10691
Hi Emanuele,
this has nothing to do with box2d.when i enter your site i get a html script virus warning via antivir.
Check your site!
Any suggestions for using movieclips as the rope segments. I’m trying to work them into the code but then nothing displays.
Awesome class BTW.
Hi Emanuele,
I don’t know whether this is the right place to post this question.
How will we implement an object whose one side is transparent ( objects hitting that side will pass through) and the other side is not (objects will bounce hitting that side). The scenario is implementation of a pipe through which a ball rolls… but objects hitting the outer side of the pipe should not bounce back….objects should move as if they are passing below/above that pipe..
Thanks in advance
LINTO
Its nice but this is better…
example:
http://www.letsmoondance.nl/
source:
http://www.box2d.org/forum/viewtopic.php?f=6&t=2094
Maw, maybe if you read the tut. It said lets start with a chain…
the rope acts as if there is no weight on the end of it.
you have created lots of useful programs great. i would suggest you to create an menu for these programs so that we can quickly reach the desired one.