Box2D的鼠标交互不是让鼠标与显示物体之间接触,实际上是创建一个鼠标关节,此关节两端分别刚体和地面。当鼠标点下时,创建一个极小的区域,遍历获取区域下面的刚体,当获取到刚体后,创建鼠标关节,随着鼠标的移动,关节刚体端跟着移动,当鼠标松开时,销毁鼠标关节。
重要代码如下:
1 private function handleEnterFrame(evt:Event):void
2 {
3 //更新鼠标位置
4 UpdateMouseWorld();
5 //不断调用鼠标拖动方法
6 mouseDrag();
7
8 var timeStep:Number = 1/30;
9 var velocityInterations:int = 10;
10 var positionIterations:int = 10;
11
12 world.Step(timeStep,velocityInterations,positionIterations);
13 //在2.1版本清除力,以提高效率
14 world.ClearForces();
15 //绘制
16 world.DrawDebugData();
17 }
18 private function UpdateMouseWorld():void
19 {
20 //物理世界的鼠标位置
21 _mouseXWorldPhys = this.mouseX / PIXEL_TO_METER;
22 _mouseYWorldPhys = this.mouseY / PIXEL_TO_METER;
23 //屏幕鼠标位置
24 _mouseXWorld = this.mouseX;
25 _mouseYWorld = this.mouseY;
26 }
27 private function getBodyAtMouse(includeStatic:Boolean = false):b2Body
28 {
29 //创建一个小的边界区域
30 _mousePVec.Set(_mouseXWorldPhys,_mouseYWorldPhys);
31 var aabb:b2AABB = new b2AABB();
32 aabb.lowerBound.Set(_mouseXWorldPhys - 0.001, _mouseYWorldPhys - 0.001);
33 aabb.upperBound.Set(_mouseXWorldPhys + 0.001, _mouseYWorldPhys + 0.001);
34 var body:b2Body = null;
35 var fixture:b2Fixture;
36
37 //回调函数的形式获取鼠标下面的刚体
38 function getBodyCallback(fixture:b2Fixture):Boolean
39 {
40 var shape:b2Shape = fixture.GetShape();
41 if(fixture.GetBody().GetType() != b2Body.b2_staticBody || includeStatic)
42 {
43 var inside:Boolean = shape.TestPoint(fixture.GetBody().GetTransform(), _mousePVec);
44 if(inside)
45 {
46 body = fixture.GetBody();
47 return false;
48 }
49 }
50 return true;
51 }
52 world.QueryAABB(getBodyCallback, aabb);
53 return body;
54 }
55
56 private function mouseDrag():void
57 {
58 //如果鼠标按下,但是没有鼠标关节
59 //创建鼠标关节
60 if(mouseDown && !_mouseJoint)
61 {
62 var body:b2Body = getBodyAtMouse();
63 if(body)
64 {
65 var md:b2MouseJointDef = new b2MouseJointDef();
66 md.bodyA = world.GetGroundBody();
67 md.bodyB = body;
68
69 md.target.Set(_mouseXWorldPhys,_mouseYWorldPhys);
70 md.collideConnected = true;
71 md.maxForce = 300.0 * body.GetMass();
72 _mouseJoint = world.CreateJoint(md) as b2MouseJoint;
73 body.SetAwake(true);
74 }
75 }
76 //如果鼠标松开,销毁鼠标关节
77 if(!mouseDown)
78 {
79 if(_mouseJoint)
80 {
81 world.DestroyJoint(_mouseJoint);
82 _mouseJoint = null;
83 }
84 }
85 //如果已经有了鼠标关节,关节目标始终设置到鼠标位置
86 if(_mouseJoint)
87 {
88 var p2:b2Vec2 = new b2Vec2(_mouseXWorldPhys,_mouseYWorldPhys);
89 _mouseJoint.SetTarget(p2);
90 }
91 }
92
93 public function handleMouseDown(e:MouseEvent):void
94 {
95 mouseDown = true;
96 }
97
98 public function handleMouseUp(e:MouseEvent):void
99 {
100 mouseDown = false;
101 }