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.

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (19 votes, average: 4.42 out of 5)
Loading ... Loading ...
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.
Be my fan on Facebook and follow me on Twitter! Exclusive content for my Facebook fans and Twitter followers

This post has 17 comments

  1. Thomas

    on November 16, 2008 at 1:05 am

    nice one. i visit your blog every day and you DO post everyday.

  2. Adrian

    on November 16, 2008 at 2:43 am

    Your tutorials are great. I´ve just started coding with AS3 and your site is great for inspiration and learning. Thanks :)

  3. Orion

    on November 16, 2008 at 9:02 am

    Great! More Box2D <3

  4. New

    on November 16, 2008 at 9:22 am

    I tried to move this to one of my own experiments but it threw me an error: ´1120: Access of undefined property stage.`

  5. anlik

    on November 17, 2008 at 2:08 am

    Sir,can you tell me if i can make the flash game with box2d in commercial use?
    Thanks

  6. buttersnack

    on November 17, 2008 at 5:05 am

    box2d wasn’t made by him

  7. Robin

    on November 17, 2008 at 12:29 pm

    nice! A good startpoint to learn box2d thanks :D

  8. Understanding pixels and meters with Box2D and how to select an object with mouse - part 2 : Emanuele Feronato

    on November 17, 2008 at 1:46 pm

    [...] previous step I used a 90×90 pixel [...]

  9. FrozenHaddock

    on November 18, 2008 at 4:55 pm

    Nice!

    More to add to my reading list when I start up AS3 properly.

  10. George Profenza

    on April 18, 2009 at 12:53 am

    Thanks! This of great help when getting started with box2das3

  11. Prototype of a Flash game like Meeblings : Emanuele Feronato

    on July 1, 2009 at 11:22 am

    [...] 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 [...]

  12. lamino

    on September 30, 2009 at 4:55 pm

    why there are no explanation nor even comments inside the code??
    it’s unclear and frustrating!

  13. Dream@Night

    on October 11, 2009 at 8:19 am

    Thanks a lot for show us how to manage box2d ! really really appreciate you !

  14. Scaling objects with Box2D : Emanuele Feronato - italian geek and PROgrammer

    on December 12, 2009 at 5:22 pm

    [...] 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 [...]

  15. Prashant

    on November 17, 2010 at 9:17 am

    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

  16. oscar

    on November 26, 2010 at 6:02 pm

    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

  17. Cassandra

    on February 15, 2011 at 5:54 am

    Really good post and you are doing best in box2d. I am not able to understand getBodyAtMouse function fully.

    can you help me?