前言:
游戏中碰撞系统的使用无处不在,比如子弹与敌机的碰撞、英雄与怪物的碰撞、技能与敌人的碰撞···这就需要用到碰撞系统了。
下面将从这几点介绍碰撞系统:
- CocosCreator提供了三种碰撞组件:Box Collider,Circle Collider,Polygon Collider;
- 碰撞的分组管理;
- 脚本代码控制碰撞事件。
一、Box Collider,Circle Collider,Polygon Collider碰撞组件介绍
添加碰撞组件:
1. Box(矩形) 碰撞组件
属性 | 说明 |
---|---|
Tag |
标签,当一个节点上有多个碰撞组件时,在发生碰撞后,可以使用此标签来判断是节点上的哪个碰撞组件被碰撞了。 |
Editing |
是否编辑此碰撞组件,只在编辑器中有效 |
Offset |
组件相对于节点的 偏移量。 |
Size |
组件的 长宽。 |
2. Circle(圆形) 碰撞组件
属性 | 说明 |
---|---|
Offset |
组件相对于节点的 偏移量。 |
Radius |
组件的 半径。 |
3. Polygon(多边形) 碰撞组件
属性 | 说明 |
---|---|
Regenerate Points |
根据组件所在节点上的 Sprite 组件的贴图像素点来自动生成相应轮廓的顶点。 |
Threshold |
指明生成贴图轮廓顶点间的最小距离,值越大则生成的点越少,可根据需求进行调节。 |
Offset |
组件相对于节点的 偏移量。 |
Points |
组件的 顶点数组。 |
二、碰撞的分组管理
1. 分组管理
分组管理,需要打开项目设置 面板进行设置,位置为 菜单栏 -> 项目 -> 项目设置。
打开 项目设置 面板后,在 分组管理 一栏可以看到 分组列表 的配置项,如下图
点击 添加分组 按钮后即可添加一个新的分组,默认会有一个 Default 分组。
需要注意的是:分组添加后是不可以删除的,不过你可以任意修改分组的名字
2. 碰撞分组配对
在 分组列表 下面可以进行 碰撞分组配对 表的管理,如下图
这张表里面的行与列分别列出了 分组列表 里面的项,分组列表 里的修改将会实时映射到这张表里。你可以在这张表里面配置哪一个分组可以对其他的分组进行碰撞检测,假设 a 行 b 列 被勾选上,那么表示 a 行 上的分组将会与 b 列 上的分组进行碰撞检测。
运行时修改节点的 group 之后,需要调用 Collider 的 apply,修改才会生效。
三、脚本代码控制碰撞事件
获取碰撞检测系统:
var manager = cc.director.getCollisionManager();
默认碰撞检测系统是禁用的,开启碰撞检测系统:
manager.enabled = true;
默认碰撞检测系统的 debug 绘制是禁用的,开启 debug 绘制:
manager.enabledDebugDraw = true;
显示碰撞组件的包围盒:
manager.enabledDrawBoundingBox = true;
碰撞系统回调
碰撞系统的回调函数,主要有三个:
- 碰撞产生时调用
onCollisionEnter: function (other, self)
- 碰撞保持时调用
onCollisionStay: function (other, self)
- 碰撞结束时调用
onCollisionExit: function (other, self)
/**
* @param {Collider} other 产生碰撞的另一个碰撞组件
* @param {Collider} self 产生碰撞的自身的碰撞组件
*/
onCollisionEnter: function (other, self) {
console.log('on collision enter');
// 碰撞系统会计算出碰撞组件在世界坐标系下的相关的值,并放到 world 这个属性里面
var world = self.world;
// 碰撞组件的 aabb 碰撞框
var aabb = world.aabb;
// 节点碰撞前上一帧 aabb 碰撞框的位置
var preAabb = world.preAabb;
// 碰撞框的世界矩阵
var t = world.transform;
// 以下属性为圆形碰撞组件特有属性
var r = world.radius;
var p = world.position;
// 以下属性为 矩形 和 多边形 碰撞组件特有属性
var ps = world.points;
},
// 当碰撞产生后,碰撞结束前的情况下,每次计算碰撞结果后调用
onCollisionStay: function (other, self) {
console.log('on collision stay');
},
// 当碰撞结束后调用
onCollisionExit: function (other, self) {
console.log('on collision exit');
}
这世上,没有谁活得比谁容易,只是有人在呼天抢地,有人在默默努力。