我们可以通过鼠标联合点击、操作世界里面的刚体。鼠标联合的原理是当鼠标点击刚体时,给隐藏的一个鼠标Sprite(位置和当前鼠标相同)和点击的刚体创建一根联合线(Joint Line),该联合线的特点是刚体会沿着联合线运动,而鼠标的移动就是改变联合线。
鼠标点击刚体获取所选刚体的步骤:
- 1.获取鼠标在物理世界中的坐标
var mouseXWorldPhys:Number = mouseX / worldScale; var mouseYWolrdPhys:Number = mouseY / worldScale;
- 2.将鼠标的坐标存放到一个鼠标向量中
var mousePVec2:b2Vec2 = new b2Vec2(); mousePVec2.Set(mouseXWorldPhys,mouseYWorldPhys);
或者
var mousePVec2:b2Vec2 = new b2Vec2(mouseXWorldPhys,mouseYWorldPhys);
- 3.创建一个包围盒,很小很小,小到可以认为可以是一个点。通过这个包围盒去获取世界中的刚体。
var aabb:b2AABB = new b2AABB(); aabb.lowerBound.Set(mouseXWorldPhys-0.001,mouseYWorldPhys-0.001); aabb.upperBound.Set(mouseXWorldPhys+0.001,mouseYWorldPhys+0.001);
- 4.使用世界的QueryAABB方法。该方法有两个参数:(1)回调函数;(2)包围盒AABB的实例,如第三步的包围盒aabb。该方法用于查询世界中处于包围盒内部的所有b2Fixture,回调函数的参数必须是b2Fixture,返回值类型会Boolean,如function callBack(fixture:b2Fixture):Boolean。当返回值为true时,重新调用该回调函数,直到返回值为false,即当点击处于动态刚体内部时候。
/**Query the world for all fixtures that potentially overlap the provided AABB. */ //Parameters //callback:Function — a user implemented callback class. It should match signature function //Callback(fixture:b2Fixture):Boolean Return true to continue to the next fixture. //aabb:b2AABB — the query box.
- 5.在回调函数中进行判断点碰撞检测。如果fixture.GetBody( ).GetTransform( )与鼠标向量碰撞,则认为鼠标点击了该刚体。(从另一个角度理解:鼠标向量点处于刚体内部中)
核心代码如下:
private function GetBodyAtMouse(includeStatic:Boolean = false):b2Body
{
mousePVec2.Set(mouseXWorldPhys, mouseYWorldPhys);
var aabb:b2AABB = new b2AABB();
aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001);
aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001);
var body:b2Body;
function getBodyCallback(fixture:b2Fixture):Boolean
{
var shape:b2Shape = fixture.GetShape();
if (fixture.GetBody().GetType() != b2Body.b2_staticBody||includeStatic)
{
var inside:Boolean = shape.TestPoint(fixture.GetBody().GetTransform(), mousePVec2);
if (inside)
{
body = fixture.GetBody();
return false;
}
}
return true;
}
world.QueryAABB(getBodyCallback, aabb);
return body;
}