让刚体听我的——鼠标拖动Box2D刚体

作者: ladeng6666 分类: Box2D 发布时间: 2012-08-18 20:35 阅读: 18,576

在前面我们学习了键盘+ApplyForce、ApplyImpulse和SetLinearVelocity来控制刚体运动。今天我们学习一下用 MouseJointDef 实现鼠标拖动刚体运动。

鼠标拖动刚体运动,这在Flash中实现起来是非常简单的:鼠标按下之后,调用startDrag()方法,这样对象就会跟随鼠标移动;鼠标弹起后,调用stopDrag()方法,停止拖动。效果如下:

听起来确实很简单,那么这个方法是否适用于Box2D刚体呢?如果你看过掉落的苹果教程,可以知道,Box2D的所有刚体都绘制在一个debugSprite中,也就是说,通过鼠标事件,我们只能获取debugSprite,并且只能执行对debugSprite的拖动,因此所有的刚体全部同时动起来,无法多每个刚体单独拖动,所以这条路行不通了。

有人可能会说了,每个刚体不是都有userData对象吗?它们都是DisplayObject,调用它们的鼠标事件,执行拖动,再更新刚体的坐标就好了。但是我想说的是,Box2D是用刚体来驱动userData的,而不是用userData来更新刚体的坐标,否则会跟Box2D内部的计算引起冲突,所以这条路也行不通了。

说了这么多,还是回到正确的方法上来。Box2D中有一个b2MouseJointDef对象,可以帮我们实现这个功能。

b2MouseJointDef是一个关节(关于关节,我会专门写一篇教程来介绍,大家稍安勿躁),用于链接鼠标和被拖动的刚体,它主要包含下面几个属性:

  • bodyA:关节连接的一个节点
  • bodyB:关节连接的另外一个节点
  • maxForce:限制鼠标关节上可以施加的最大的力,这里通常需要乘以刚体的质量multiplier * mass * gravity

了解了鼠标关节(这里我只简单的介绍这么多,在后面的教程我会专门介绍Box2D里的关节),接下来,我们开始编写拖动过程。

鼠标是否滑过刚体

首先,要确定是否在刚体上,并找出这个刚体。在Flash中,我们调用DisplayObject的MOUSE_OVER方法,可以判断鼠标是否滑过该对象。

与Flash不同,Box2D用b2World世界的QueryPoint方法来实现这个功能,QueryPoint方法如下:

QueryPoint方法会遍历world中所有的刚体,判断p点是否在刚体上,如果是,则将刚体对应的b2Fixture传入到callBack函数中。然后我可以利用b2Fixture.GetBody()方法获取刚体,具体代码如下:

拖动刚体

找到鼠标点击的刚体后,下面是拖动刚体。前面说过,我们是用鼠标关节MouseJointDef来实现拖动刚体,所以针对拖动过程,我创建鼠标关节,然后把点击的刚体设置为关节的一个节点,然后鼠标关节的目标点位鼠标点,并实时更新就好了,代码如下:

完成后的效果如下:

完整的代码和注释如下:

另外,代码中我用到了LDEasyBox2D,如果你不熟悉,请参考这里

源代码下载

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

7条评论
  • xiao_h

    2012 年 9 月 11 日 下午 3:54

    太棒了~
    从学到的知识点越来越多了,希望等整个系列学完后,我们都能独立制作属于自己的物理游戏,呵呵,感谢拉登大叔!!!

    1. ladeng6666

      2012 年 9 月 11 日 下午 8:42

      加油吧!让我们一起进步!!

  • Grey

    2012 年 11 月 1 日 上午 10:00

    菜鸟求助:
    在这里面怎么不能给刚体穿上衣怎么不行呢?
    在使用LDEasyBox2D创建刚体的时候,addChild(bodyRequest.userData);
    会报错:1180: 调用的方法 addChild 可能未定义。

    1. ladeng6666

      2012 年 11 月 1 日 下午 6:53

      请不要在LDEasyBox2D里使用addChild方法,因为它没有继承DisplayObject,同样也请确认你的文档类是DisplayObject的子类。否则就吹出现addChild没有定义的错误。

  • Pingback: PivotJoint关节实现Nape刚体拖动 « Ladeng6666-专业的Flash/AS3爱好者
  • justlin

    2013 年 10 月 23 日 上午 10:41

    现在用鼠标的话,一次只能拖一个,能不能做成多点的,一次能拖多个呢?

    1. ladeng6666

      2013 年 10 月 27 日 下午 9:07

      应该可以,但是要创建多个鼠标关节,你可以尝试一下!

发表评论

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