Flash physics draw game with a car using QuickB2
QuickB2 is a complete abstraction of Box2D, providing grouped hierarchies, extensible classes, and event-driven callbacks.
The high-level interface enables developers to create physics simulations that are impractical to write using Box2D’s API alone.
It takes care of things that you don’t want to, so that you can concentrate on your game.
Among its top features we can find:
* Soft-bodies.
* Top-down car physics.
* Friction in z-direction (top-down friction).
* Pixel-based units.
* Individual polygons may be concave and have any number of vertices.
* All kinds of joints, including built-in spring joints.
* WYSIWYG editing environment for Flash CS5.
Combining one of the official examples with the drawing concept introduced during the creation of Way of an Idea Box2D prototype I ended up with this script:
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 As3Math.consts.*; import As3Math.geo2d.*; import QuickB2.events.*; import QuickB2.misc.*; import QuickB2.objects.*; import QuickB2.objects.joints.*; import QuickB2.objects.tangibles.*; import QuickB2.stock.*; import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.KeyboardEvent; public class Main extends Sprite { private var car:qb2Group; private var world:qb2World; private var left:Boolean=false; private var right:Boolean=false; private var drawing:Boolean=false; private var canvas:Sprite = new Sprite(); private var pointsArray:Array; private var drawDistance:int=60; private var saveX:int; private var saveY:int; public function Main():void { world=qb2Stock.newDebugWorld(new amVector2d(0,10),this.graphics); world.start(); var rectangle:qb2PolygonShape=qb2Stock.newRectShape(new amPoint2d(200,200),100,25,0); world.addObject(rectangle); world.addObject(new qb2StageWalls(stage)); var carOrigin:amPoint2d=new amPoint2d(200,150); var wheelRadius:Number=20; var bodyLength:Number=60; var bodyHeight:Number=20; var alteredFriction:Number=2; car = new qb2Group(); var wheel1:qb2CircleShape=qb2Stock.newCircleShape(carOrigin.clone().incX(- bodyLength/2),wheelRadius,1); var wheel2:qb2CircleShape = qb2Stock.newCircleShape(carOrigin.clone().incX( bodyLength / 2), wheelRadius, 1); var carBody:qb2PolygonShape = qb2Stock.newEllipseShape(carOrigin.clone().incY( -bodyLength / 2), new amVector2d(bodyLength/2 + 10, 0), bodyHeight, 18, 0, 2 * AM_PI, 2); wheel1.friction=wheel2.friction=alteredFriction; wheel1.angularDamping=wheel2.angularDamping=.1; var leftSpring:qb2PistonJoint=new qb2PistonJoint(carBody,wheel1,carBody.position.clone().incX(- bodyLength/2),wheel1.position); var rightSpring:qb2PistonJoint = new qb2PistonJoint(carBody, wheel2, carBody.position.clone().incX( bodyLength/2), wheel2.position); leftSpring.springK=50; rightSpring.springK=50; leftSpring.springDamping=2; rightSpring.springDamping=2; leftSpring.freeRotation=true; rightSpring.freeRotation=true; car.addObject(carBody); car.addObject(wheel1); car.addObject(wheel2); car.addObject(leftSpring); car.addObject(rightSpring); world.addObject(car); addChild(canvas); canvas.graphics.lineStyle(5); car.addEventListener(qb2UpdateEvent.POST_UPDATE, updateCar); stage.addEventListener(MouseEvent.MOUSE_DOWN,mousePressed); stage.addEventListener(MouseEvent.MOUSE_MOVE,mouseMoved); stage.addEventListener(MouseEvent.MOUSE_UP,mouseReleased); stage.addEventListener(KeyboardEvent.KEY_DOWN,keyPressed); stage.addEventListener(KeyboardEvent.KEY_UP,keyReleased); } private function keyPressed(e:KeyboardEvent):void { switch (e.keyCode) { case 37 : left=true; break; case 39 : right=true; break; } } private function keyReleased(e:KeyboardEvent):void { switch (e.keyCode) { case 37 : left=false; break; case 39 : right=false; break; } } private function mousePressed(e:MouseEvent):void { drawing=true; canvas.graphics.moveTo(mouseX,mouseY); pointsArray=new Array(); saveX=mouseX; saveY=mouseY; pointsArray.push(saveX); pointsArray.push(saveY); } private function mouseMoved(e:MouseEvent):void { if (drawing) { var dist_x:int=mouseX-saveX; var dist_y:int=mouseY-saveY; if (dist_x*dist_x+dist_y*dist_y>drawDistance*drawDistance) { canvas.graphics.lineTo(mouseX,mouseY); saveX=mouseX; saveY=mouseY; pointsArray.push(saveX); pointsArray.push(saveY); } } } private function mouseReleased(e:MouseEvent):void { drawing=false; var segments:int=pointsArray.length/2-1; for (var i:int=0; i<segments; i++) { var body:qb2Body=qb2Stock.newLineBody(new amPoint2d(pointsArray[i*2],pointsArray[i*2+1]),new amPoint2d(pointsArray[i*2+2],pointsArray[i*2+3]),10,0,qb2Stock.ENDS_ROUND); world.addObject(body); } canvas.graphics.clear(); canvas.graphics.lineStyle(5); } private function updateCar(e:qb2UpdateEvent):void { var torque:Number=0; if (left) { torque-=10; } if (right) { torque+=10; } for (var i:int=0;i<car.numObjects;i++) { var object:qb2Object=car.getObjectAt(i); if (object is qb2CircleShape) { (object as qb2CircleShape).applyTorque(torque); } } } } } |
which once executed produces this result:
Control the car with left and right arrow keys, and draw ramps with the mouse.
Now I am doing the same thing with the normal Box2D library to show you the differences.
They can be easily customized to meet the unique requirements of your project.















(27 votes, average: 4.85 out of 5)










This post has 18 comments
itsme
Very nice :), but could you please add the leaning feature
leon
grrr I can’t stop falling upside down lol.
nice tutorial x)
Chris Moeller
Wow, very nice find!!
I had decided to write some box2d articles, and realized again how annoying not using “pixel based units” were.
It looks like it’s open sourced too, wicked cool!
Lynnhom Hsueh
I encounter this error when I compiled the source of QuickB2:
Can not find the definition of cmodule.Box2D
Hawdon
Incredible.
Vladimir
I like it…the only thing I don’t like is that by using it you are adding another layer to your system…but that is a cost that I’m willing to accept :)
joy
wow, what box2d version this library use ? is this another wrapper like quickbox2d ?
so to summarize, now we can use box2d physics with just box2d, wck, quickbox2d (2.0 only), or QuickB2
mauricio
This is great…. nice work. Quick question, quickb2 has better performance than box2d?
Balsa
Umm, this has nothing to do with the tut but how do you made those boxes in like RRODE before the start of each level ?
Mandeep
QuickBox2D doesn’t seem to be maintained anymore, so it’s definitely nice to see another library that simplifies Box2D.
ravikumar
superb nice …………nice
Balsa
I’ve noticed that you can have one wheel on the ramp and still be able to move
ryan
What’s the as3math package? I can’t seem to find any info on it, and don’t see it included in the quickb2 source.
Eric
Thanks! Now I can build some bike games for fun ^^
santosh
how we can show our own defined shapes in box2d….
BaconTech - BaconCasinos Techblog
[...] a look at this example by Emanuele Feronato or the demo reel. Posted: maj 31st, 2011 Categories: AS3 Tags: Comments: No [...]
MaR
Would be nice to see this example with custom graphics.
prabakaran
very nice could you explain me how to create ellipse shape dynamic body in normal box2d version 2.1