Creating a sling with Box2D using joints
February 7, 2009 by Emanuele Feronato
Filed Under Actionscript 3, Box2D, Flash, Game design • 15 Comments
Filed Under Actionscript 3, Box2D, Flash, Game design • 15 Comments
This is an example about the creation of a sling using joints and motors.
Click the mouse to break the joint and release the bullet. Try to hit the stack of boxes.
I used a distance joint, a revolute joint and a motor. The code does not need to be commented because there is nothing new, just look how I destroy the joint to launch the bullet at lines 122-123
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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | 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 sling extends Sprite { var mouseJoint:b2MouseJoint; var mousePVec:b2Vec2=new b2Vec2; var bd:b2BodyDef; var the_box:b2PolygonDef=new b2PolygonDef; var the_pivot:b2CircleDef=new b2CircleDef; var the_rev_joint:b2RevoluteJointDef=new b2RevoluteJointDef; var the_dist_joint:b2DistanceJointDef = new b2DistanceJointDef(); var dest_joint:b2DistanceJoint; public function sling() { // 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); // the ground var final_body:b2Body; var the_body:b2BodyDef; var the_box:b2PolygonDef; the_body = new b2BodyDef(); the_body.position.Set(8.5, 13); the_box = new b2PolygonDef(); the_box.SetAsBox(8.5, 0.5); the_box.friction=0.3; the_box.density=0; final_body=m_world.CreateBody(the_body); final_body.CreateShape(the_box); final_body.SetMassFromShapes(); // some boxes for (var i:int=0; i<7; i++) { the_body = new b2BodyDef(); the_body.position.Set(12, 12-i); the_box = new b2PolygonDef(); the_box.SetAsBox(0.5,0.5); the_box.friction=0.3; the_box.density=0.5; final_body=m_world.CreateBody(the_body); final_body.CreateShape(the_box); final_body.SetMassFromShapes(); } // pivot for revolute joint the_pivot.radius=0.2; the_pivot.density=0; bd=new b2BodyDef ; bd.position.Set(3,6.5); var rev_joint:b2Body=m_world.CreateBody(bd); rev_joint.CreateShape(the_pivot); rev_joint.SetMassFromShapes(); // box for the revolute joint the_box.SetAsBox(2,0.1); the_box.density=0.01; the_box.friction=1; the_box.restitution=0.1; bd=new b2BodyDef ; bd.position.Set(3,6.5); var rev_box:b2Body=m_world.CreateBody(bd); rev_box.CreateShape(the_box); rev_box.SetMassFromShapes(); // revolute joint the_rev_joint.Initialize(rev_joint,rev_box,new b2Vec2(3,6.5)); the_rev_joint.enableMotor=true; the_rev_joint.motorSpeed=10; the_rev_joint.maxMotorTorque=1000; var joint_added:b2RevoluteJoint=m_world.CreateJoint(the_rev_joint) as b2RevoluteJoint; // bullet the_box.SetAsBox(0.2,0.2); the_box.density=1.0; the_box.friction=0.4; the_box.restitution=0.1; bd = new b2BodyDef(); bd.position.Set(2, 5); var bullet:b2Body=m_world.CreateBody(bd); bullet.CreateShape(the_box); bullet.SetMassFromShapes(); // distance joint the_dist_joint.Initialize(bullet, rev_box, new b2Vec2(2,5),new b2Vec2(1,6.5)); the_dist_joint.collideConnected=true; dest_joint=m_world.CreateJoint(the_dist_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 { m_world.DestroyJoint(dest_joint); dest_joint=null; 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; } } |
How would you turn it into a game?
» Flash Templates provided by Template Monster are pre-made web design products developed using Flash technology.
They can be easily customized to meet the unique requirements of your project.
They can be easily customized to meet the unique requirements of your project.
15 Responses to “Creating a sling with Box2D using joints”
Leave a Reply
Trackbacks
-
Simulating a hook with Box2D : Emanuele Feronato on
September 29th, 2009 3:59 pm
[...] same script we saw at Box2D joints: Distance Joint with some modifications and the concept saw at Creating a sling with Box2D using joints when we must remove the [...]
- 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)






Might be an interesting concept for a game you have there :)
Amazing job Emanuele!
More one nice example of Box2D!
There is a bug with dragging. Try dragging the ball and then lines get weird.
The function destroyMouse seens bugged :S
i use like this:
public function destroyMouse(evt:MouseEvent):void
{
if (mouseJoint)
{
mundo.DestroyJoint(mouseJoint);
mouseJoint=null;
}
}
Great and really interesting.
Something is wrong there… =X
You should have had it rotating the other direction. Would be easier to use.
@Gawd
Yeah, i try to change this is this code, but i encouter this problem:
How change de rotation? Simple change the value to negative right?
the_rev_joint.motorSpeed=-10;
the_rev_joint.maxMotorTorque=-1000;
NO! This not work :(
hahah
hey i found a glitch
once the bullet is released you can pick it up
not a glitch
but if you click about 1in up from the edge of the catapult it creats a piont and then the bullet goes crazy
I just tried this tutorial within the web page, and I got an ActionScript error alert.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Box2D.Dynamics::b2World/DestroyJoint()
at sling/destroyMouse()
I don’t know that much about Box2D, or if it’s even important, but I thought you might want to know. It occurs when I click on the bullet, drag it, and then release it.
Bruno Mikoski leave the torque alone its only the speed that needs to be changed to a negative.
Also the stack falls over on its own if you leave it alone any ideas how to fix this problem. I’ve tried adjusting the friction and density with no lucky anyone?
the sling initially works, but then it all gets buggy as hell :)
Nice concept :)
yeah !there is a bug !But ,I think you have solved it ! haha
for other vistors ,I’ll add some codes to solve it !
public function destroyMouse(evt:MouseEvent):void {
if (dest_joint) {
m_world.DestroyJoint(dest_joint);
}
dest_joint=null;
if (mouseJoint) {
m_world.DestroyJoint(mouseJoint);
mouseJoint=null;
}