Cocos Creator 开发实战——射线测试

 近期写了一款基于射线测试的小游戏,本篇会介绍射线测试知识和一些坑,保证大家会用并且避免引擎bug。
       国际惯例先上效果

射线测试基础知识
       先看一遍官网,在页面的最下面部分。射线测试需要用到物理引擎,接下来开始教学。

开启物理引擎
       物理系统默认是关闭的,如果需要使用物理系统,那么首先需要做的事情就是开启物理系统,否则你在编辑器里做的所有物理编辑都不会产生任何效果。

onLoad () {
cc.director.getPhysicsManager().enabled = true;
},

添加物理碰撞物体
添加组件

用到的是物理引擎 添加的碰撞体必须是物理组件里的碰撞体
添加组件-》物理组件-》Collider组件-》Box
       type设置撑Static
       否则会有重力自己下落

通过触摸点触发射线测试
代码挂载在Canvas节点下

onLoad () {
cc.director.getPhysicsManager().enabled = true;
//添加触摸监听 通过触摸点讲解射线测试
this.node.on(‘touchstart’, this.TouchStart, this)
},

TouchStart (event) {
//获得触摸点本地坐标位置
let p1 = event.getLocation()
//射线测试结束点位置 从开始点向右发射:x坐标增加1000 射线测试
let p2 = cc.v2(p1.x+1000, p1.y)
this.rayTest(p1, p2)
},

rayTest (p1, p2) {
var results = cc.director.getPhysicsManager().rayCast(p1, p2, cc.RayCastType.Closest);

for (var i = 0; i < results.length; i++) {
    //两点之间检测出来的点的数组
    var result = results[i];
    //射线穿过的是哪一个碰撞体。
    var collider = result.collider;
    //射线穿过的碰撞体的世界坐标
    var point = result.point;
    //碰撞体在相交点的表面的法线向量。
    var normal = result.normal;
    //相交点在射线上的分数。
    var fraction = result.fraction;
    //打印出碰撞点的坐标
    cc.log('point:', point)
}

},

检测类型介绍

cc.RayCastType.Any
检测射线路径上任意的碰撞体,一旦检测到任何碰撞体,将立刻结束检测其他的碰撞体,最快。

cc.RayCastType.Closest
检测射线路径上最近的碰撞体,这是射线检测的默认值,稍慢。

cc.RayCastType.All
检测射线路径上的所有碰撞体,检测到的结果顺序不是固定的。在这种检测类型下一个碰撞体可能会返回多个结果,这是因为 box2d 是通过检测夹具(fixture)来进行物体检测的,而一个碰撞体中可能由多个夹具(fixture)组成的,慢。更多细节可到 物理碰撞组件 查看。

cc.RayCastType.AllClosest
检测射线路径上所有碰撞体,但是会对返回值进行删选,只返回每一个碰撞体距离射线起始点最近的那个点的相关信息,最慢

result返回值介绍

实际开发过程中的坑

cc.director.getPhysicsManager().rayCast(p1, p2, cc.RayCastType.Closest);
1
       这句话会出现bug,原因是因为运行加载的时候物理引擎这部分没有加载完成,所以底层封装的变量没有new出来。
       解决方法: 加一个计时器。

this.schedule(function() {
this.rayTest()
}, 0.01);
1
2
3
结果

在这基础上增加表现形式
创建一个星星 检测到射线测试的点 自动移动到检测点的位置

拖拽进入场景

移动
properties: {
m_star: cc.Node,
},

       拖入星星

rayTest (p1, p2) {
    var results = cc.director.getPhysicsManager().rayCast(p1, p2, cc.RayCastType.Closest);

    for (var i = 0; i < results.length; i++) {
        //两点之间检测出来的点的数组
        var result = results[i];
        //射线穿过的是哪一个碰撞体。
        var collider = result.collider;
        //射线穿过的碰撞体的世界坐标
        var point = result.point;
        //碰撞体在相交点的表面的法线向量。
        var normal = result.normal;
        //相交点在射线上的分数。
        var fraction = result.fraction;

        // cc.log('point:', point)

        //世界坐标转成当前节点坐标
        let localPos = this.node.convertToNodeSpaceAR(point)
        //移动
        this.m_star.runAction(cc.moveTo(1,localPos))

    }
},


结果

————————————————
版权声明:本文为CSDN博主「游戏创造者黄昱」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/creator_HY/article/details/104074282

作者: 执着小钟

执着小钟

发表评论