虽然laya的libs声明文件中Laya.physics.I.world为any类型,但通过查看源码我们就能发现laya的2D物理采用的是Box2D,点击进入。把Laya.physics.I.world输出到控制台我们可以发现这个是laya.physics.js文件中的b2World类型,而且有对应的射线检测方法,如下图
通过搜索raycast关键字我们可以发现laya已经在box2d.d.ts声明文件中声明了对应接口。
上面的文件的js源码如下:
RayCast(...args) {
if (args[0] instanceof b2RayCastCallback) {
this._RayCast(args[0], args[1], args[2]);
}
else {
this._RayCast(null, args[0], args[1], args[2]);
}
}
_RayCast(callback, point1, point2, fn) {
const input = b2World.RayCast_s_input;
input.maxFraction = 1;
input.p1.Copy(point1);
input.p2.Copy(point2);
this.m_contactManager.m_broadPhase.RayCast(input, (input, proxy) => {
const fixture_proxy = proxy.userData;
// DEBUG: b2Assert(fixture_proxy instanceof b2FixtureProxy);
const fixture = fixture_proxy.fixture;
const index = fixture_proxy.childIndex;
const output = b2World.RayCast_s_output;
const hit = fixture.RayCast(output, input, index);
if (hit) {
const fraction = output.fraction;
const point = b2World.RayCast_s_point;
point.Set((1 - fraction) * point1.x + fraction * point2.x, (1 - fraction) * point1.y + fraction * point2.y);
if (callback) {
return callback.ReportFixture(fixture, point, output.normal, fraction);
}
else if (fn) {
return fn(fixture, point, output.normal, fraction);
}
}
return input.maxFraction;
});
}
有了源码,有了接口,我们是不是就可以照着上面使用了呢?可以,但是有一些坑,坑是什么已经不重要,大家按照我下面的使用方法使用即可:
var world = Laya.Physics.I.world;
console.log(world);
let p0 = {x:0, y:0};
let p1 = {x:640, y:1386};
/**
* 回调函数
* @param fixture 定制器, 这个类型在laya的声明文件里注明了,大家可以搜索查阅
* @param point 碰撞点,这里注意这个点的实际坐标需要 *Laya.Physics.PIXEL_RATIO
* @param normal 法线
* @param fraction 比例,该比例系数为 起点到该碰撞点的距离/射线的长度
* @returns
*/
let callback = function(fixture:b2Fixture, point:{x:number, y:number}, normal:{x:number, y:number}, fraction:number) {
console.log(fixture);
console.log(point);
console.log(normal);
console.log(fraction);
return 1; // 这里如果 直接返回0 则碰撞到第一个点就会立即返回, 返回1 则会一直检测到终点为止的所有碰撞信息
}
world.RayCast(p0, p1, callback);