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 (11 votes, average: 4.36 out of 5)
Loading ... Loading ...
If you found this post useful, please consider a small donation.
» 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.

14 Responses to “Understanding pixels and meters with Box2D and how to select an object with mouse – part 1”

  1. Thomas on November 16th, 2008 1:05 am

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

  2. Adrian on November 16th, 2008 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 16th, 2008 9:02 am

    Great! More Box2D <3

  4. New on November 16th, 2008 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 17th, 2008 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 17th, 2008 5:05 am

    box2d wasn’t made by him

  7. Robin on November 17th, 2008 12:29 pm

    nice! A good startpoint to learn box2d thanks :D

  8. FrozenHaddock on November 18th, 2008 4:55 pm

    Nice!

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

  9. George Profenza on April 18th, 2009 12:53 am

    Thanks! This of great help when getting started with box2das3

  10. lamino on September 30th, 2009 4:55 pm

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

  11. Dream@Night on October 11th, 2009 8:19 am

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

Leave a Reply




Trackbacks

  1. Understanding pixels and meters with Box2D and how to select an object with mouse - part 2 : Emanuele Feronato on November 17th, 2008 1:46 pm

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

  2. Prototype of a Flash game like Meeblings : Emanuele Feronato on July 1st, 2009 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 [...]

  3. Scaling objects with Box2D : Emanuele Feronato - italian geek and PROgrammer on December 12th, 2009 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 [...]

flash games company