Box2D is getting more and more popular among Flash developers, but it still lacks of adeguate tutorials and documentation about making games with it.
Andrew McGrath from Gamersgarden released a great tutorial about drawing boxes on the fly on Box2D.
Every detail of the script is fully commented, so you won’t miss anything, and you will get something like this:
Click and drag with the mouse to draw boxes on the fly.
This is the source code:
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.*;
public class andrew extends Sprite {
public var m_dbgSprite;
public var m_world:b2World;
public var m_phys_scale:Number = 30.0;
public var m_timestep:Number = 1.0/30.0;
public var m_iterations:Number = 10.0;
//initial box coordinates when we first press mouse down
public var initX:Number = 0.0;
public var initY:Number = 0.0;
public var drawing:Boolean = false;
public function andrew() {
/*
A Box2D world needs three parameters: a b2AABB, gravity
and a Booleand deciding whether or not to let bodies sleep
when they are not being simulated.
This saves CPU so should always be left on :)
*/
var gravity:b2Vec2 = new b2Vec2(0,9.8);
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-1000,-1000);
worldAABB.upperBound.Set(1000,1000);
m_world = new b2World(worldAABB,gravity,true);
//Setup Debug Draw - So that Box2D draws the shapes for us
m_dbgSprite = new Sprite();
addChild(m_dbgSprite);
SetDebugDraw();
//Add Our Ground
AddStaticBox(300/m_phys_scale,440/m_phys_scale,300/m_phys_scale,50/m_phys_scale);
addEventListener(Event.ENTER_FRAME,Update);
stage.addEventListener(MouseEvent.MOUSE_DOWN,mousePressed);
stage.addEventListener(MouseEvent.MOUSE_MOVE,mouseMoved);
stage.addEventListener(MouseEvent.MOUSE_UP,mouseReleased);
}
public function mousePressed(e:MouseEvent) {
//Store initial X and Y position
initX = e.localX;
initY = e.localY;
drawing = true;
}
public function mouseMoved(e:MouseEvent) {
if (drawing) {
//Simply draw the "ghost" of the box we are about to add
graphics.clear();
graphics.beginFill(0xFF0000,0.5);
graphics.drawRect(initX,initY,e.localX-initX,e.localY-initY);
}
}
public function mouseReleased(e:MouseEvent) {
graphics.clear();
drawing = false;
//Coordinates of bottom-right of box (when drawing from left to right)
var finalX:Number = e.localX;
var finalY:Number = e.localY;
//Correct if drawing from right to left
if (finalX < initX) {
//If so, swap initX and finalX
var tempX:Number = initX;
initX = finalX;
finalX = tempX;
}
if (finalY < initY) {
//If so, swap initY and finalY
var tempY:Number = initY;
initY = finalY;
finalY = tempY;
}
//Work out the half-width and height of the box
var boxHalfWidth:Number = Math.abs((finalX-initX)/2);
var boxHalfHeight:Number = Math.abs((finalY-initY)/2);
if (boxHalfWidth > 0 && boxHalfHeight > 0) {
AddBox((finalX-boxHalfWidth)/m_phys_scale,(finalY-boxHalfHeight)/m_phys_scale,boxHalfWidth/m_phys_scale,boxHalfHeight/m_phys_scale);
}
}
/*
NOTE: AddBox takes the _x,_y and halfwidth and halfheight parameters
in METRES not PIXELS. This means when you call this function, always
DIVIDE a pixel size by m_phys_scale to get it in meteres.
*/
public function AddBox(_x:Number,_y:Number,_halfwidth:Number,_halfheight:Number) {
var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.position.Set(_x,_y);
var boxDef:b2PolygonDef = new b2PolygonDef();
boxDef.SetAsBox(_halfwidth,_halfheight);
boxDef.density = 1.0;
boxDef.friction = 0.3;
boxDef.restitution = 0.2;
var body:b2Body = m_world.CreateBody(bodyDef);
body.CreateShape(boxDef);
body.SetMassFromShapes();
}
public function AddStaticBox(_x:Number,_y:Number,_halfwidth:Number,_halfheight:Number) {
var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.position.Set(_x,_y);
var boxDef:b2PolygonDef = new b2PolygonDef();
boxDef.SetAsBox(_halfwidth,_halfheight);
boxDef.density = 0.0;
var body:b2Body = m_world.CreateBody(bodyDef);
body.CreateShape(boxDef);
body.SetMassFromShapes();
}
public function Update(e:Event) {
//We need to do this to simulate physics
m_world.Step(m_timestep,m_iterations);
}
public function SetDebugDraw() {
//Set Debug Draw (hidden here to reserve space in constructor.)
var dbgDraw:b2DebugDraw = new b2DebugDraw();
dbgDraw.m_sprite = m_dbgSprite;
dbgDraw.m_drawScale = m_phys_scale;
dbgDraw.m_fillAlpha = 0.8;
dbgDraw.m_lineThickness = 2.0;
dbgDraw.m_drawFlags = 0x0001 | 0x0002;
m_world.SetDebugDraw(dbgDraw);
}
}
}
And this is the source code to download.
Is there anyone willing to code the routine to draw circles triangles in the same way?
Thank you Andrew!