Dragging objects with Box2D Flash

This is ideally the next part after Understanding pixels and meters with Box2D and how to select an object with mouse – part 2, but it’s so important understanding how to drag objects with Box2D that I decided to change the title.

Anyway, in this uncommented example (a commented one will follow) you can select any crate with the mouse and drag it.

Changing at line 89 the mouse_joint.maxForce value will affect gameplay.

This is the source code:

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
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.*;
	import Box2D.Dynamics.Joints.*;
	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 var mouseJoint:b2MouseJoint;
		public function cratetest() {
			addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, on_mouse_down);
			stage.addEventListener(MouseEvent.MOUSE_UP, on_mouse_up);
			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);
			if (mouseJoint) {
				var mouseXWorldPhys = mouseX/pixels_in_a_meter;
				var mouseYWorldPhys = mouseY/pixels_in_a_meter;
				var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
				mouseJoint.SetTarget(p2);
			}
			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(evt:MouseEvent):void {
			var body:b2Body = GetBodyAtMouse();
			if (body) {
				var mouse_joint:b2MouseJointDef = new b2MouseJointDef;
				mouse_joint.body1 = m_world.GetGroundBody();
				mouse_joint.body2 = body;
				mouse_joint.target.Set(mouseX/pixels_in_a_meter, mouseY/pixels_in_a_meter);
				mouse_joint.maxForce = 10000;
				mouse_joint.timeStep = m_timeStep;
				mouseJoint = m_world.CreateJoint(mouse_joint) as b2MouseJoint;
			}
		}
		public function on_mouse_up(evt:MouseEvent):void {
			if (mouseJoint) {
				m_world.DestroyJoint(mouseJoint);
				mouseJoint = null;
			}
		}
		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:

Enjoy dragging and dropping crates with your mouse.

Download the source code.

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (27 votes, average: 4.41 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 27 comments

  1. Cool

    on November 20, 2008 at 8:25 pm

    Very cool!

  2. Terry

    on November 21, 2008 at 5:21 am

    Nice tutorial I was having an idea to create a game by dragging the boxes and it helps a lot. :)

  3. Colin Diam

    on November 21, 2008 at 8:44 am

    Can you please make a turoial how to make game like mytheria

  4. Peter

    on November 21, 2008 at 3:50 pm

    COOOOOOOOOLLLLL!!!!!! :D

  5. zap

    on November 21, 2008 at 4:52 pm

    excelente

  6. Goodbye AS2… : Emanuele Feronato

    on November 26, 2008 at 1:03 pm

    [...] new cool libraries are written in AS3, just think about BOX2D and the games you can make with [...]

  7. Jacob

    on December 26, 2008 at 11:05 am

    Won’t Work

    1046: Type was not found or was not a compile-time constant: b2Body. “public function GetBodyAtMouse(includeStatic:Boolean=false):b2Body {“

  8. vijay

    on December 28, 2008 at 1:35 am

    hi,I’m very much interested to create games in flash can u help me

  9. zap

    on February 18, 2009 at 1:41 pm

    Im trying to put a top limit…

    //arriba
    boxDef.SetAsBox(8.5, 14.5);
    bodyDef.position.Set(8.5, -0.5);
    boxDef.friction = 1;
    boxDef.density = 0;
    bodyDef.userData = new floor();
    bodyDef.userData.width = 8.5 * 2 * pixels_in_a_meter;
    bodyDef.userData.height = 0.5 * 2 * pixels_in_a_meter;
    addChild(bodyDef.userData);
    body = m_world.CreateBody(bodyDef);
    body.CreateShape(boxDef);

    …the limit is in a correct position but my box have a bad movement, what´s the problem?

  10. zap

    on February 18, 2009 at 1:59 pm

    solucionado!!! Thanksssssss a lot

  11. ben

    on April 3, 2009 at 5:39 pm

    Fixed :
    worked well if addin my b2body a m_userData when created rather than addin userData to the body Def…
    now everything works fine….
    Is a empty b2Body always considered as null ???
    Strange ????

  12. bigLama

    on June 4, 2009 at 4:28 pm

    Please can you fully explain the code iside the function function GetBodyAtMouse.
    Thanks

  13. Godfrey Cao

    on August 25, 2009 at 10:27 am

    thankssssss a lot !
    regarding this function (GetBodyAtMouse), i did not understand all of them .
    especially line 112. what is it used for?

  14. Trevor

    on September 2, 2009 at 5:19 am

    Great!

    Now where is Box3D???

    I am SERIOUS!!!!

  15. Elf

    on October 17, 2009 at 10:08 pm

    What faster using GetBodyAtMouse() or
    private function on_mouse_down(e:MouseEvent):void
    {
    for(var body:b2Body=world.GetBodyList();body;body=body.m_next)
    {
    if(body.m_userData==e.target) break;
    }
    if (body)
    {
    …do something…
    }
    }
    ?
    but my method depend on object count.

  16. Despecrew

    on November 3, 2009 at 9:42 pm

    Great !!

    I would like to know how can I delineate the area of drag and drop ?

    PS: sorry for my bad benglish.. :/

  17. Vlad

    on December 1, 2009 at 11:28 pm

    Emanuele, might I ask why you always put everything in the same class ? is it for the simplicity of the tutorial ?

  18. Emanuele Feronato

    on December 2, 2009 at 11:16 am

    Having a single script to show is easier to display and understand for newbies.

  19. Jaleel

    on January 22, 2010 at 1:22 pm

    Emanuele, great job. thanks for u r code its really helps us to move forward with box2d. keep it up.

  20. Nick

    on March 22, 2010 at 2:18 am

    I am trying to integrate this into my own Box2D project where i have about 20 objects that are just falling to the ground, but when I click on an object that is falling it will just STOP – it won’t let me drag it…do you know why that might be?

  21. Lilx

    on March 28, 2010 at 2:59 pm

    The Vector class doesn’t work with Flash CS3 and Flash player 9 :/

  22. Alex

    on August 3, 2010 at 9:40 am

    i get this error:

    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at HelloBoxWorld/GetBodyAtMouse()

    the line that flash says is wrong is this one:

    var count:int = m_world.Query(aabb, shapes, k_maxCount);

    can someone help

  23. MKEason

    on August 23, 2010 at 1:34 pm

    I met a very strange problem!

    If I compile this source in Flex Builder with Flex SDK without any change except embed those necessary images with meta tag, then everything stops in the begining.

    I tried other sources too, they all failed! Have no idea why. Can everybody help me on this?

    Thanks in advanced.

  24. Volvo S60 Pinball game – Things I learnt « Tahir Ahmed's thoughts

    on October 13, 2010 at 4:25 pm

    [...] Emanuele Feronato has written a blog tutorial using QuickBox2D and a tutorial done earlier using Box2DFlash alone. It clearly shows you how easy it is to setup Box2DFlash when used with [...]

  25. Riccardo Bartoli

    on November 24, 2010 at 6:30 pm

    Ciao Emanuele,

    Grazie per questi tutorial! Sto cercando di aggiornare un file vecchio di 2 anni, e ho problemi con il metodo GetShapeList() e GetBody()


    mousePVec.Set(xMouse, yMouse);

    var starShape : b2Shape = star.GetShapeList();
    var inside : Boolean = starShape.TestPoint(starShape.GetBody().GetXForm(), mousePVec);

    Sai aiutmarmi perfavore? Grazie.

  26. Ape Asylum

    on August 16, 2011 at 3:07 pm

    can anyone explain to me why i am getting this error:

    Line 100 1046: Type was not found or was not a compile-time constant: b2Body.

    I am kind of stuck, the source code does not work!!! help please

  27. Crisdava

    on September 3, 2011 at 5:21 pm

    Para poder ejecutarlo se necesitan el Box2d Version 2.2

    Descargarlo aqui:
    http://sourceforge.net/projects/box2dflash/files/box2dflash/Box2DFlashAS3_2.0.2/Box2DFlashAS3_2.0.2_.zip/download