cocos2d-x十七(简单的碰撞检测 实践篇 下)

最后这一节记录一下cloudBomb中冲击力影响的实现和碰撞过滤。利用chipmunk中的冲击力函数可以在导弹爆炸时弹飞附近的刚体,达到最真实的爆炸所产生的物理影响,其实在游戏中也可以用来做释放技能之类的影响区域,下面是代码:

首先需要拿到导弹爆炸后,在影响范围内的刚体坐标:

  1. cpSpaceNearestPointQuery(space,shape->body->p,100,12,CP_NO_GROUP,actionNearestPoint,NULL);  

	cpSpaceNearestPointQuery(space,shape->body->p,100,12,CP_NO_GROUP,actionNearestPoint,NULL);


上面第一个参数是物理空间,第二个是导弹shape刚体的坐标,第三个参数是最大影响范围(距离),第四个是shage的层标识,第五个是组(设定是无组),第六个是获取导弹附近刚体坐标后的回调函数,最后一个是回调时使用的自定义参数。其中第四和第五个参数用来限制影响的对象,比如只作用于一组对象……然后是回调代码:
  1. //获取爆炸点附近坐标后的回调函数  
  2. static void actionNearestPoint(cpShape *shape, cpFloat distance, cpVect point, void *data);  

	//获取爆炸点附近坐标后的回调函数
	static void actionNearestPoint(cpShape *shape, cpFloat distance, cpVect point, void *data);


  1. //获取爆炸点附近坐标后的回调函数  
  2. void HelloWorld::actionNearestPoint(cpShape *shape, cpFloat distance, cpVect point, void *data){  
  3. const cpFloat splash = 100.0;  
  4. const cpFloat strength = 400.0;  
  5. cpBody *dbody = shape->body;  
  6.           
  7.         // Use the nearest point to calculate the impulse to apply.  
  8.         // This makes for a pretty good approximation.  
  9.         //强度设定  
  10.         cpFloat intensity = 1.0 - cpvdist(dbody->p, point)/splash;  
  11.         //冲击力计算  
  12.         cpVect impulse = cpvmult(cpvnormalize(cpvsub(dbody->p, point)), strength*intensity);  
  13.         //应用冲击到对应的刚体  
  14.         cpBodyApplyImpulse(dbody,impulse,cpvsub(point, dbody->p));  
  15.           
  16.         // Play with the boxes' emotions.  
  17.         Box *dbox = (Box*)dbody->data;  
  18.                 //这里只做了个表情的输出日志,有兴趣的可以自己做着玩  
  19.         dbox->makeUpset();  
  20. }  

//获取爆炸点附近坐标后的回调函数
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不是同一属性值时,两者是不会有碰撞发生的。

最后看看导弹在碰撞墙体爆炸后箱子被弹飞的效果图:

源代码下载:http://download.csdn.net/detail/cyistudio/5558209