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.可以判断 两个物体 相碰 两个物体的相对位置, 自身在上 还是在下,在左还是在右。
也还可以 进行 碰撞的方向 判断 ,上下左右 那个方向 碰过来的 。这个还需要 进一步 学习