自定义Box2D刚体碰撞处理函数

作者: ladeng6666 分类: Box2D 发布时间: 2012-09-16 19:09 阅读: 22,677

谁动了我的刚体——Box2D刚体碰撞中,我们学会了用b2Contact和b2ContactListener来处理发生碰撞的刚体,但是正如我之前所说的,在b2Contact或b2ContactListener中,我们获取的bodyA和bodyB无法知道哪个是游戏主角,哪个是敌人,分不出个青红皂白,所以只能一棒子打死啦。所以今天我们学习在b2Body类中自定义一个碰撞处理函数。

用b2Contact和b2ContactListener来处理发生的碰撞,就免不了下面这样的代码:

具体我在谁动了我的刚体——Box2D刚体碰撞中已经讲过了,最大的缺点就是要反复进行多次判断。

原因是因为我们分不出bodyA和bodyB具体是哪个对象,不过刚体知道他们自己是谁,我们可以在b2Body里定义一个碰撞处理函数,如contactWith(),而这个函数中可以用this应用刚体自己,另个可以用参数传入,然后让对碰撞刚体分别调用bodyA.contactWith(bodyB),bodyB.contactWith(bodyA)就可以轻松分出青红皂白啦。

好吧,我再讲细一点。首先在b2Body中声明一个beginContactHanlder公共变量,我们可以在外部自定义这个函数。

然后再定义一个beginContactWith公共函数,在碰撞发生时,我们可以在b2Contact或b2ContactListener处理函数中直接用bodyA.contactWith(bodyB),bodyB.contactWith(bodyA)来实现碰撞处理。

最后在Main类中自定义了beginContactHanlder函数。注意,这个函数一定要包含两个参数,分别表示刚体自己,和与它发生碰撞的刚体。

这样我们可以只对需要侦听碰撞事件的刚体设置碰撞函数,并进行碰撞处理。如谁动了我的刚体——Box2D刚体碰撞中的例子,我们只需要在刚体与地面刚体发生碰撞时让他们分别往右或左移动,所以只要对地面刚体设置beginContactHanlder函数就可以啦。

同样的效果:

完整的代码和注释如下:

 

 源文件下载地址

 

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

11条评论
  • sunny

    2012 年 9 月 16 日 下午 8:43

    把拉登兄目前为止的所有box2d教程都看了一遍,收获真是不小!
    期待你的新教程~另外我也该思考一下,利用目前所学到的这些知识,能否创建一个有意思的物理游戏,谢谢拉登!

    1. ladeng6666

      2012 年 9 月 16 日 下午 9:39

      谢谢你的支持,做一个简单的小游戏应该是没有问题的,后续我会讲一些游戏实例的。期待吧…

  • sZpt_CBD

    2012 年 9 月 17 日 上午 10:30

    嗯“拉登兄。。我想知道有没可能做一个人物动态的刚体???就是刚体是随着那个图的形状来变动。?还是说是用别的方法来实现那效果的.?

  • xdd

    2012 年 11 月 9 日 上午 11:41

    HI,感谢你的教程.
    我自己写的Demo,发现无法在碰撞检测自定义类里destory b2Body,这是框架限定功能了么.

  • xdd

    2012 年 11 月 9 日 下午 1:33

    看到了,原来是刚体在碰撞时,world是lock状态,要等刚体成休眠时才可destory

    1. ladeng6666

      2012 年 11 月 11 日 下午 11:05

      对的,world有时候会出现lock状态,这时候不进行模拟。

      1. xdd

        2012 年 11 月 13 日 下午 1:10

        感谢!

  • 小扶

    2013 年 5 月 31 日 下午 7:42

    那个。。。虽然是个很小的问题。。。但是觉得很容易因为不注意造成后续的错误。。。就是句柄的单词拉登大师你拼错了=。=
    在这篇文章中全部用的hanlder,应该是handler 。就是beginContactHandler。因为我自己就是贴一部分敲一部分然后出现问题了。。。。。。orz

    1. ladeng6666

      2013 年 5 月 31 日 下午 8:53

      sorry啦,以后会注意啦!谢谢你的关注!

  • 天琅古琊

    2015 年 3 月 5 日 下午 5:17

    请问一下,想要清除所有刚体的时候需不需要先清除贴图?,清除贴图是用SetUserData(null)吗?
    for (var body:b2Body = world.GetBodyList(); body; body = body.GetNext())
    {
    if (body.GetUserData() != null)
    {
    if (body.GetUserData().name.indexOf("brick") != -1)
    {
    body.SetUserData(null);
    world.DestroyBody(body);
    }
    }
    }
    这样好像没有办法删除刚体?贴图也没有反应?

    1. ladeng6666

      2015 年 3 月 8 日 下午 9:26

      DestroyBody()就可以删除刚体,你的方法是正确的。SetUserData(null);是解除贴图与刚体的绑定关系,如果你所谓的彻底删除,是把贴图也删除掉的话,应该相应的使用Flash的removeChild()函数。更多问题,可以微信或qq联系我(qq:328800655)

xdd进行回复 取消回复

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