谁动了我的刚体——Box2D碰撞检测

作者: ladeng6666 分类: Box2D 发布时间: 2012-09-14 21:24 阅读: 12,438

今天我们来学习用Box2D的b2Contact和b2ContactListener来获取碰撞对象(Box2D中用contact一词来表示碰撞,知道这一点,对后面的理解会有帮助)。

Box2D是一个非常强大的2D物理引擎,可以帮我们实现精确的碰撞检测,并模拟2D碰撞。但有时候只知道”碰撞了”是不够了,就像我在”谈谈碰撞检测“里讲到的,针对不同的游戏,碰撞后的处理方式是不同的,可能是变更运动轨迹(如桌球游戏)、可能是销毁对象(如愤怒的小鸟)等等。而实现这一切可能的效果,首先要先知道碰撞的对象,所以就有了今天的教程。

Box2D中获取碰撞对象的方法有两种。一个是通过world.GetContactList().bodyA和bodyB来获取碰撞双方;另外一个是自定义Box2D.Dynamics下的b2ContactListener类,侦听碰撞后的事件,然后做进一步的处理。下面我们来看看具体的实现方法。

一、用world.GetContactList()方法获取碰撞对象

world.GetContactList()会返回一个b2Contact对象。前面我说过的,Box2D中contact是碰撞的意思,所以可以猜想到,b2Contact肯定跟碰撞有关。是的,b2Contact用来管理碰撞的shape,任何有超过两个及以上接触点的刚体,Box2D都认为发生了碰撞,并用b2Contact来管理。

通过b2Contact的GetFixtureA()和GetFixtureB()方法,我们可以获取碰撞对象的b2Fixture属性引用,进而获取碰撞对象。具体代码举例如下:

二、用b2ContactListener获取碰撞对象

从b2ContactListener的名字上大家应该可以猜到,它是Box2D对象碰撞检测侦听器,当刚体之间发生碰撞时,Box2D引擎会自动调用这个类的相关方法,然后做进一步的处理。这些方法包括:

  •  BeginContact:当碰撞发生时触发该方法
  • EndContact:当碰撞结束时触发该方法

使用b2ContactListener的方法有两种。一、修改b2ContactListener的BeginContact和EndContact方法,添加碰撞处理代码;二、继承b2ContactListener类,如自定义一个myContactListener子类,然后重写子类的BeginContact和EndContact方法,然后将子类传递给world.world.SetContactListener()方法,自定义碰撞侦听器。

三、如何使用Box2D的碰撞对象

在Flash中编写碰撞检测代码时,通常我们会用A对象(如游戏主角)的hitTest或hitTestObject方法检查它与另外一个对象的碰撞,当碰撞发生时,分别对A和B进行碰撞处理。这里我们很清楚哪个是A对象(游戏主角),那个是B对象(敌人)。

但是在b2Contact或b2ContactListener中,我们获取的bodyA和bodyB无法知道哪个是游戏主角,哪个是敌人,分不出个青红皂白,所以只能一棒子打死啦。我的意思是,比如我现在想找到碰撞的对象是否是游戏主角,那么就得分别确认一下bodyA和bodyB了,游戏碰撞对象种类越多,判断越复杂。具体在下面的实例中,我会在代码注释里解释。

在下面的示例中,有一个静态的矩形对象,屏幕顶部会不断的掉下圆形和矩形刚体,当发生碰撞后,圆形刚体会向左运动,矩形会向右运动。

完整的代码和注释如下:

代码中用到了我写的静态类LDEasyBox2D,可以有效的简化代码,具体请参考这里或者googleCode

源文件下载地址

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

2条评论
  • Aimee

    2013 年 4 月 16 日 上午 7:48

    yo wnqb habmq maigrir mjmertcct vgqog

    btrtui comment perdre des hanches rtysiym qvyvgsgweo

    ywehvvm b wsia creme anti cellulite buaxvg gbxmb

    dbyuoc auday comment maigrir du ventre rtziuivrt imcgu

  • kingBook

    2013 年 4 月 28 日 下午 3:34

    /**
    *如果创建两个一样大小的矩形Body,假设BoxData.name分别为”p1″, “p2″;
    *将他们的y设为一样,
    *然后在”p1”, “p2″下创建矩形Body地面, BoxData.name为”ground”;
    *——————-片断代码如下—————–
    */
    if ($contactList != null)
    {
    var $bodyA:b2Body = $contactList.GetFixtureA().GetBody();
    var $bodyB:b2Body = $contactList.GetFixtureB().GetBody();
    trace($bodyA.GetUserData().name, $bodyB.GetUserData().name);
    /*输出:
    p1 ground
    p1 ground
    p1 ground
    …*/
    //输出永远只能看到”p1″||”p2″
    //求解???
    }

发表评论

电子邮件地址不会被公开。 必填项已用*标注