box2d 获得碰撞冲量

Box2D教程1-创建碰撞世界
Box2D教程2-鼠标交互
Box2D教程3-刚体绑定外观
Box2D教程4-复杂刚体的复杂外观
Box2D教程5-碰撞检测



源码下载    Box2DTutorial06CheckCollisionStrength.zip (403.5 KB, 下载次数: 132) 
两个物体产生碰撞的时候,除了检测是否碰撞了,很多时候我们需要知道碰撞强度有多大,比如愤怒的小鸟,要根据碰撞的强度决定是否消去障碍物。这一个教程解释如何获取碰撞强度。 
碰撞的强度在物理上用冲量(Impluse)表示,在经典力学里,冲量等于物体动量的变化。

冲量公式
I = Ft (单位 N*s)
如果有恒力F,作用在质量为m、静止的物体上,经过时间t,会产生什么效果呢?由Ft=mat=mv看出,力与时间的乘积Ft越大,静止的物体获得的速度v就越大;Ft越小,物体的速度就越小。

冲量是矢量
冲量的方向由力的方向确定。如果在力的作用时间内,力的方向保持不变,则力的方向就是冲量的方向。

冲量与动量的关系
运动物体的质量和速度的乘积叫动量,p=mv,国际单位是千克米每秒。
在恒力F作用下,质量为m的物体在时间t内,速度由v变化到v′。根据牛顿第二定律,有F=ma式中F为物体所受外力的合力。等式两边同乘时间t,Ft=mat=mv′-mv,因此I=p′-p
总结说,质量一定的物体碰撞之后获取的速度可以用来衡量碰撞强度,其取决于碰撞力与时间的乘积,及冲量。因此box2D中,我们要判断碰撞强度,需要获取碰撞时的冲量,而box2D已经为你提供了方便的获取方式。具体获取方法如下。

在教程五中我们已经说明了如何进行碰撞检测。创建自定义的CustomContactListener,覆盖其中的BeginContact和EndContact来获取碰撞开始和碰撞结束。而获取碰撞冲量,这时需要覆盖另外一个方法PostSolve(contact:b2Contact, impulse:b2ContactImpulse),我们看到此方法有两个参数
  • b2contact:碰撞对象,可以获取两个碰撞物体
  • impluse:碰撞冲量,及我们所需要的衡量碰撞强度的参数
impluse冲量是一个数组,具有两个元素,normalImpulses和tangentImpulses,都是矢量Vector类型

  • normalImpulses 碰撞普通合力产生的冲量
  • tangentImpulses 模拟切线方向摩擦力所产生的冲量(实际trace时总是0,可能是我的刚体原因)


在这个教程中,覆盖PostSolve方法抛出碰撞事件,携带冲量数组作为参数,在主程序侦听此事件,输出冲量数值。

CustomContactListener.as覆盖PostSolve方法
  1. override public function PostSolve(contact:b2Contact,impluse:b2ContactImpulse):void
  2. {
  3.         var collisionEvent:CollisionEvent = new CollisionEvent(CollisionEvent.POST_SOLVE);
  4.         if(contact.GetFixtureA().GetBody().GetUserData() != null && contact.GetFixtureB().GetBody().GetUserData() != null)
  5.         {
  6.                 collisionEvent.impluse = impluse;
  7.                 eventDispatcher.dispatchEvent(collisionEvent);
  8.         }
  9. }
复制代码
碰撞事件CollisionEvent.as
  1. package comingx.jingle.events
  2. {
  3.         import Box2D.Dynamics.b2ContactImpulse;

  4.         import flash.events.Event;

  5.         public class CollisionEvent extends Event
  6.         {
  7.                 public static const COLLISION_START:String = "collision_start";
  8.                 public static const COLLISION_END:String = "collision_end";
  9.                 public static const POST_SOLVE:String = "post_solve";

  10.                 public var bodyAName:String = "";
  11.                 public var bodyBName:String = "";
  12.                 //碰撞冲量数组
  13.                 public var impluse:b2ContactImpulse;


  14.                 public function CollisionEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
  15.                 {
  16.                         super(type, bubbles, cancelable);
  17.                 }
  18.         }
  19. }
复制代码
在主程序中侦听输出
  1.                 private function initContactListener():void
  2.                 {
  3.                         var customContactListener:CustomContactListener = new CustomContactListener();
  4.                         customContactListener.eventDispatcher.addEventListener(CollisionEvent.COLLISION_START, handleCollisionStart);
  5.                         customContactListener.eventDispatcher.addEventListener(CollisionEvent.COLLISION_END, handleCollisionEnd);
  6.                         //碰撞处理结束侦听
  7.                         customContactListener.eventDispatcher.addEventListener(CollisionEvent.POST_SOLVE,handlePostSolve);
  8.                         world.SetContactListener(customContactListener);
  9.                 }

  10.                  /**
  11.                  * 输出碰撞冲量 
  12.                  * @param evt 碰撞事件
  13.                  * 
  14.                  */                
  15.                 private function handlePostSolve(evt:CollisionEvent):void
  16.                 {
  17.                         console.addInfo("碰撞冲量为:" + evt.impluse.normalImpulses[0].toString());
  18.                         if(evt.impluse.normalImpulses[0] > 30)
  19.                         {
  20.                                 //你的逻辑处理,比如像愤怒小鸟一样让障碍物爆炸
  21.                         }
  22.                 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值