box2d 碰撞检测

当你用到box2d后,box2d的碰撞监听检测 是最常用的内容之一。

在这里简要说明一下,为后面的内容做点铺垫。呵呵

1.通过继承并实现b2ContactListener这个类,

class MyContactListener : public b2ContactListener
{
    ……
}

2.进源代码你可以看到这个类中有 4个回调函数,


class MyContactListener : public b2ContactListener
{
      //碰撞开始 即发现物体间重叠点时通知
       virtual void BeginContact(b2Contact* contact);

      /// 碰撞结束 结束重叠后通知
       virtual void EndContact(b2Contact* contact) ;

       //碰撞处理前 即根据物理定律处理刚体前
       virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
 
       //碰撞处理后  
      virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);
}

重写这4个函数。在相关的函数中加入你想要碰撞处理的内容。 即可

3.把你这个监听类加入到世界中

world->SetContactListener(mContactListener);

你就可以监听碰撞事件了。

这里有几个注意的地方:

1。我们不能在上面这几个回调函数中删除摧毁刚体。因为上面调用都是在box2d的b2World::Step方法中,此时正在进行遍历物理世界的world->GetBodyList()

对物理时间世界进行演算。

官方说明:“你可能会以碰撞来施加伤害,并试图摧毁关联的角色和它的刚体。然而,Box2D 并不允许你在回调中改变物理世界,因 为你可能会摧毁 Box2D 正在运算的对象,造成野指针。” 

如果强在里面加摧毁物体函数,你可能会发现world是被锁定的。如需要摧毁,只能用一个容器把需要的处理事件保存起来,带step方法执行完毕后再处理这些容器;具体的摧毁动态刚体的方法在下下章写。。。

2。如果你在PreSolve()里改变了物体的位置,比如使他们后退一点,他们互不碰撞,那么他们不会调用EndContact();

3。你有时候很希望他们可以选择碰撞的方向:比如 天上一堵墙 从下面可以穿过不会碰撞,上面接触会碰撞 不能穿过。这属于box2d中OneSidedPlatform的内容。具体的我会在下一章写。

但要注意 如果你想碰撞后修改成穿过的状态 应该用 contact->SetEnabled(false);   而不是 myShapeDef.isSensor = true;  你在代码里可以尝试下两个的区别。还是有点小明显。虽然isSensor 是让

测碰撞而不产生碰撞应。 

box2d单纯的碰撞检测还是比较好看明白。还是附个小例子吧~

下载例子dome :附件

原文地址:https://www.cnblogs.com/cooka/p/3222030.html