CocosCreator.碰撞系统

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27032631/article/details/85345369

Cocos Creator 内置了一个简单的碰撞检测系统,使用这个系统需要
提前开启 碰撞检测系统。
默认是 关闭的 这点需要特别注意,不然就会出现 明明加了碰撞盒,却检测不到碰撞

var manager = cc.director.getCollisionManager();
manager.enabled = true;

系统中有三个重要的方法:
1.onCollisionEnter
2.onCollisionStay
3.onCollisionExit

// 目前自己用到的
onCollisionEnter:function(other, self)
    {         
           var otherAabb = other.world.aabb;
           
            var selfAabb = self.world.aabb;
            
            var otherPreAabb = other.world.preAabb.clone()
            
            var selfPreAabb = self.world.preAabb.clone();
            
            //处理Y轴上的碰撞
            selfPreAabb.y = selfAabb.y;
            
            otherPreAabb.y = otherAabb.y;
            
            if(cc.Intersection.rectRect(selfPreAabb,otherPreAabb))
            {
                if(selfPreAabb.y<otherPreAabb.y)
                {
                        console.log("在下方");
                }else
                {        
                     console.log("在上方");
                }             
                var intersection=new cc.Rect();
                selfPreAabb.intersection(intersection, otherPreAabb);
                this.node.y+=intersection.height;   
            }
        }

来说说 以上这个方法的用途
首先这两个参数 是Collision类型的
world.aabb 这个是什么?
从源码可以找到 他是一个对象,每一个Collider 都需要进行一个初始化的操作 ,在这里面 就声明了一个world对象
这个对象里设置了一些 collision 会用到的 属性 比如 AABB, Matrix。了解有这几个属性就好了,目前用到的是
AABB这个东东,从源码可以看到这是一个 Rect。

//  Collider 的初始化
initCollider: function (collider) {
        if (!collider.world) {
            let world = collider.world = {};
            world.aabb = cc.rect();
            world.preAabb = cc.rect();
            world.matrix = math.mat4.create();

            world.radius = 0;

            if (collider instanceof cc.BoxCollider) {
                world.position = null;
                world.points = [cc.v2(), cc.v2(), cc.v2(), cc.v2()];
            }
            else if (collider instanceof cc.PolygonCollider) {
                world.position = null;
                world.points = collider.points.map(function (p) {
                    return cc.v2(p.x, p.y);
                });
            }
            else if (collider instanceof cc.CircleCollider) {
                world.position = cc.v2();
                world.points = null;
            }
        }
    },

// Rect类中 判断 两个矩阵是否相交
Rect.proto.intersects = function (rect) {
    var maxax = this.x + this.width,
        maxay = this.y + this.height,
        maxbx = rect.x + rect.width,
        maxby = rect.y + rect.height;
    return !(maxax < rect.x || maxbx < this.x || maxay < rect.y || maxby < this.y);
};
// Rect类 中 返回 两个矩阵的重叠部分
Rect.proto.intersection = function (out, rectB) {
    var axMin = this.x, ayMin = this.y, axMax = this.x + this.width, ayMax = this.y + this.height;
    var bxMin = rectB.x, byMin = rectB.y, bxMax = rectB.x + rectB.width, byMax = rectB.y + rectB.height;
    out.x = Math.max(axMin, bxMin);
    out.y = Math.max(ayMin, byMin);
    out.width = Math.min(axMax, bxMax) - out.x;
    out.height = Math.min(ayMax, byMax) - out.y;
    return out;
};

cc.Intersection.rectRect(selfPreAabb,otherPreAabb))
判断 两个Collision 在Y轴上 是否 有发生 碰撞了

var intersection=new cc.Rect();
selfPreAabb.intersection(intersection, otherPreAabb);

发生碰撞 之后 返回这个重叠部分 重叠部分是一个 Rect 类型
可以取得重叠部分 的Height 或者 Width 做一些自己需要的操作

以上 只是用到了 在Y 轴上的处理 X轴上的处理也是 类型的

这个方法 可用在那些方面呢?
1.简单点的 碰撞 进入 处理 一个物体是不是碰到了 另一个物体。
2.一个物体 碰到另一个 物体 的 位置 变化 ,比如 一个物体 扎进了另一个物体 ,如果 要将 物体 从中 回退 就可以 利用 重叠 部分的宽高做处理。
3.可以判断 两个物体 相碰 两个物体的相对位置, 自身在上 还是在下,在左还是在右。

也还可以 进行 碰撞的方向 判断 ,上下左右 那个方向 碰过来的 。这个还需要 进一步 学习

猜你喜欢

转载自blog.csdn.net/qq_27032631/article/details/85345369