最后这一节记录一下cloudBomb中冲击力影响的实现和碰撞过滤。利用chipmunk中的冲击力函数可以在导弹爆炸时弹飞附近的刚体,达到最真实的爆炸所产生的物理影响,其实在游戏中也可以用来做释放技能之类的影响区域,下面是代码:
首先需要拿到导弹爆炸后,在影响范围内的刚体坐标:
cpSpaceNearestPointQuery(space,shape->body->p,100,12,CP_NO_GROUP,actionNearestPoint,NULL);
上面第一个参数是物理空间,第二个是导弹shape刚体的坐标,第三个参数是最大影响范围(距离),第四个是shage的层标识,第五个是组(设定是无组),第六个是获取导弹附近刚体坐标后的回调函数,最后一个是回调时使用的自定义参数。其中第四和第五个参数用来限制影响的对象,比如只作用于一组对象……然后是回调代码:
//获取爆炸点附近坐标后的回调函数
static void actionNearestPoint(cpShape *shape, cpFloat distance, cpVect point, void *data);
//获取爆炸点附近坐标后的回调函数
void HelloWorld::actionNearestPoint(cpShape *shape, cpFloat distance, cpVect point, void *data){
const cpFloat splash = 100.0;
const cpFloat strength = 400.0;
cpBody *dbody = shape->body;
// Use the nearest point to calculate the impulse to apply.
// This makes for a pretty good approximation.
//强度设定
cpFloat intensity = 1.0 - cpvdist(dbody->p, point)/splash;
//冲击力计算
cpVect impulse = cpvmult(cpvnormalize(cpvsub(dbody->p, point)), strength*intensity);
//应用冲击到对应的刚体
cpBodyApplyImpulse(dbody,impulse,cpvsub(point, dbody->p));
// Play with the boxes' emotions.
Box *dbox = (Box*)dbody->data;
//这里只做了个表情的输出日志,有兴趣的可以自己做着玩
dbox->makeUpset();
}
至于箱子精灵的自定义代码其实和乌云精灵的差不多,只是用的是物理精灵类,所以基本只是改变一个图片纹理而已,然后需要给shape的layers属性设定一下 shape->layers=12; 这个shape中的layers属性其实和层的概念是一样的,同时也可作为碰撞的过滤规则,像我在前面例子中没有设定shape的layers属性,所以物理空间里的任何对象都会发生碰撞,而在原例中,导弹与箱子或者导弹之间并不会发生实质性的碰撞,就是因为定义了这样的过滤规则。当导弹和箱子的layers不是同一属性值时,两者是不会有碰撞发生的。
最后看看导弹在碰撞墙体爆炸后箱子被弹飞的效果图: