Understanding pixels and meters with Box2D and how to select an object with mouse – part 1
This will be the longest post title in blogging history… anyway I am about to explain you two things that seem to be still unclear about AS3 version of Box2D.
The first one is Box2D measuring units that may seem weird until you realize Box2D works with meters where 1mt = 30 pixels.
The second one is the capability of selecting single objects with the mouse thanks to the custom GetBodyAtMouse. There are even people willing to pay for those information in the official forum.
So I modified the HelloWorld example in my own way in order to have some 90×90 ox sided crates (texture by http://www.reallyreallygoodthings.com/) I can make “jump” and “torque” clicking the mouse on them.
This is the uncommented actionscript, I will post the step-by-step explaination tomorrow.
|
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 |
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 cratetest extends Sprite { public var m_world:b2World; public var m_iterations:int = 10; public var m_timeStep:Number = 1/30; public var mousePVec:b2Vec2 = new b2Vec2(); public var real_x_mouse:Number; public var real_y_mouse:Number; public var pixels_in_a_meter = 30; public var worldAABB:b2AABB = new b2AABB() public var gravity:b2Vec2 = new b2Vec2(0.0, 10.0); public function cratetest() { addEventListener(Event.ENTER_FRAME, Update, false, 0, true); stage.addEventListener(MouseEvent.CLICK,on_mouse_down); worldAABB.lowerBound.Set(-100.0, -100.0); worldAABB.upperBound.Set(100.0, 100.0); m_world = new b2World(worldAABB, gravity, true); var body:b2Body; var bodyDef:b2BodyDef; var boxDef:b2PolygonDef; bodyDef = new b2BodyDef(); bodyDef.position.Set(8.5, 13.5); boxDef = new b2PolygonDef(); var ground_width = 8.5; var ground_height = 0.5; boxDef.SetAsBox(ground_width, ground_height); boxDef.friction = 0.3; boxDef.density = 0; bodyDef.userData = new floor(); bodyDef.userData.width = ground_width * 2 * pixels_in_a_meter; bodyDef.userData.height = ground_height * 2 * pixels_in_a_meter; addChild(bodyDef.userData); body = m_world.CreateBody(bodyDef); body.CreateShape(boxDef); body.SetMassFromShapes(); for (var i:int = 1; i <=5; i++) { bodyDef = new b2BodyDef(); bodyDef.position.x = Math.random() * 15 + 1; bodyDef.position.y = Math.random(); var crate_width:Number = 1.5; var crate_height:Number = 1.5; boxDef = new b2PolygonDef(); boxDef.SetAsBox(crate_width, crate_height); boxDef.density = 1.0; boxDef.friction = 0.5; boxDef.restitution = 0.2; bodyDef.userData = new crate(); bodyDef.userData.width = crate_width * 2 * pixels_in_a_meter; bodyDef.userData.height = crate_height * 2* pixels_in_a_meter; body = m_world.CreateBody(bodyDef); body.CreateShape(boxDef); body.SetMassFromShapes(); addChild(bodyDef.userData); } } public function Update(e:Event):void { m_world.Step(m_timeStep, m_iterations); for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next) { if (bb.m_userData is Sprite) { bb.m_userData.x = bb.GetPosition().x * pixels_in_a_meter; bb.m_userData.y = bb.GetPosition().y * pixels_in_a_meter; bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI); } } } public function on_mouse_down(e:MouseEvent) { var body:b2Body = GetBodyAtMouse(); if (body) { body.ApplyImpulse(new b2Vec2(0.0, -80.0), body.GetWorldCenter()); body.ApplyTorque(450); } } public function GetBodyAtMouse(includeStatic:Boolean=false):b2Body { real_x_mouse = (stage.mouseX)/pixels_in_a_meter; real_y_mouse = (stage.mouseY)/pixels_in_a_meter; mousePVec.Set(real_x_mouse, real_y_mouse); var aabb:b2AABB = new b2AABB(); aabb.lowerBound.Set(real_x_mouse - 0.001, real_y_mouse - 0.001); aabb.upperBound.Set(real_x_mouse + 0.001, real_y_mouse + 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].m_body.IsStatic() == false || includeStatic) { var tShape:b2Shape = shapes[i] as b2Shape; var inside:Boolean = tShape.TestPoint(tShape.m_body.GetXForm(), mousePVec); if (inside) { body = tShape.m_body; break; } } } return body; } } } |
and this is the result:
Click on a crate to make it jump and torque. Download the source code and wait for the step-by-step tutorial.
They can be easily customized to meet the unique requirements of your project.





(20 votes, average: 4.45 out of 5)






This post has 18 comments
Thomas
nice one. i visit your blog every day and you DO post everyday.
Adrian
Your tutorials are great. I´ve just started coding with AS3 and your site is great for inspiration and learning. Thanks :)
Orion
Great! More Box2D <3
New
I tried to move this to one of my own experiments but it threw me an error: ´1120: Access of undefined property stage.`
anlik
Sir,can you tell me if i can make the flash game with box2d in commercial use?
Thanks
buttersnack
box2d wasn’t made by him
Robin
nice! A good startpoint to learn box2d thanks :D
Understanding pixels and meters with Box2D and how to select an object with mouse - part 2 : Emanuele Feronato
[...] previous step I used a 90×90 pixel [...]
FrozenHaddock
Nice!
More to add to my reading list when I start up AS3 properly.
George Profenza
Thanks! This of great help when getting started with box2das3
Prototype of a Flash game like Meeblings : Emanuele Feronato
[...] you click and hold anywhere on the stage, every ball in a 4 meters radius (read this post and this post too if you don’t know how to convert meters to pixels) will be attracted [...]
lamino
why there are no explanation nor even comments inside the code??
it’s unclear and frustrating!
Dream@Night
Thanks a lot for show us how to manage box2d ! really really appreciate you !
Scaling objects with Box2D : Emanuele Feronato - italian geek and PROgrammer
[...] you know how to select a Box2D object with the mouse. If you aren’t familiar with it, read Understanding pixels and meters with Box2D and how to select an object with mouse – part 1 and part [...]
Prashant
I have download the source file.
and also Box2d zip folder.
and i have a error
1046:Type was not found or was not a compile-time constant: b2Body
i am new in as3
Thanks
oscar
I download you example, but it don’t work because flash don’t find b2PolygonDef. I download the latest Box2D, exactly Box2DFlashAS3 2.1a … (others examples work fine, because they haven’t b2PolygonDef)
can you help me? Thanks
Cassandra
Really good post and you are doing best in box2d. I am not able to understand getBodyAtMouse function fully.
can you help me?
lawrence
Brilliant