掉落的苹果——b2Body刚体

作者: ladeng6666 分类: Box2D 发布时间: 2012-06-05 12:58 阅读: 44,107

上一节中,我们认识了Box2D世界,学习了它的创建方法。今天我们一起来扮演牛顿,认识一下Box2D世界中掉落的苹果。在开始之前,我们想先说明两个内容:
1. Box2D中的计量单位是米

在Box2D中的计量单位是米m,而不是Flash中的像素px,在布置坐标时,要进行一个转换,1米=30个像素。所以Box2D中(a,b)点对于Flash中的(a*30,b*30)的位置,或者说Flash中的(c,d)位置对应Box2D中的(c/30,d/30)位置。

2. Box2D用b2DebugDraw进行模拟调试

Box2D是一个物理引擎,不会向Flash显示列表中添加任何显示对象。不过Box2D中有一个b2DebugDraw类,可以绑定一个显示对象,进行模拟调试。至于如何在Box2D中添加显示对象,在以后的学习中,我们再深入讨论。
b2DebugDraw的用法:

  1. 创建一个空的Sprite对象debugSprite,并添加到舞台中
  2. 创建一个b2DebugDraw对象debugDraw,并设置它的m_sprite属性值为debugSprite.
  3. 用world的SetDebugDraw方法,绑定debugDraw

3. World的更新:

Box2D的和Flash一样,需要实时更新,Flash中有ENTER_FRAME,b2world有step,其参数一表示模拟的时长,二表示限制碰撞后检测程式运行的次数,防止死循环。

刚体与DisplayObject的区别

掉落的苹果实际上是Box2D里的一个刚体b2Body,当然可以把他理解成Flash中的sprite,不过:

A. b2Body

1. 它是Box2D中的一个物理模拟对象,不是可显示对象,但是可以通过b2DebugDraw来进行调试模拟
2. 它的计量单位是米m
3. 它通过b2World.createBody()来创建

B. Sprite

1. 它是显示对象,通过addChild添加即可显示
2. 它的计量单位是像素px
3. 通过new来创建,然后addChild添加后直接显示在舞台上

刚体创建的过程,与AS中new一个对象,addChild到舞台中显示比起来要复杂很多,刚体的创建可以看做是一个工厂模式,根据你的需求(b2BodyDef)生产指定的刚体

刚体的创建过程可以分为两个步骤:

1. 创建刚体需求b2BodyDef。

在这个需求中,我们可以包括下面的内容:
a) position:刚体的坐标位置,单位是米m
b) angle:刚体的角度
c) 其他,在以后的学习中我们会陆续介绍

2. b2World工厂用createBody方法创建刚体产品,并自动将其添加到Box2D世界中,然后返回该刚体。

定义刚体形状

到目前位置,我们已经成功添加了一个刚体。
讲个题外话,今天我同时的老婆生了,听到这个消息,你会问的第一个问题是什么?”男孩,女孩?”答对了!
把刚体当成我们的孩子吧。创建一个刚体后,你应该问什么?”方的,圆的?”(这孩子好挫啊!)非常正确。刚体的形状不是与生俱来的,需要用一个b2Shape的子类对象指定。刚体形状的创建过程同样也是一个工厂模式。

这个创建过程与b2Body的创建过程是一样的。我们的形状需求b2ShapeDef可以报考下面的内容:

a) density:质量
b) friction:表面摩擦力
c) restitution:表面张力,这个值越大,刚体越硬
d) SetAsBox:设置刚体为矩形
e) 其他,在以后的学习中我们会陆续介绍

好了创建b2Body刚体的完整过程就讲完了。我们在总结一下:

1. 创建刚体需求b2BodyDef
2. Box2D世界工厂根据需求用createBody方法创建刚体
3. 创建刚体形状需求b2ShapeDef的子类对象
4. B2Body工厂根据需求用createShape方法创建形状

实例练习

掌握了上面的内容,我相信完成下面的这个练习就不是什么难事了。
点击舞台的任意位置创建一个方形刚体。

代码

 

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

42条评论
  • yzxwml

    2012 年 6 月 5 日 下午 2:48

    很好的教程,学习了,谢谢拉登兄

    1. ladeng6666

      2012 年 6 月 6 日 下午 12:10

      谢谢你的关注,我会努力写出更多教程的!

  • yaoayao

    2012 年 6 月 14 日 上午 7:12

    我下的这个box2d2.1a怎么没有b2PolygonDef这个类啊

    1. ladeng6666

      2012 年 6 月 22 日 上午 7:45

      在box2d2.1a中貌似都统一成了b2FixtureDef,你搜索一下啊

  • kk

    2012 年 6 月 28 日 上午 8:53

    2. b2World工厂用createBody方法创建刚体产品,并自动将其添加到Box2D世界中,然后返回该刚体。

    body = world.CreateBody(bodyRequest);

    你这个body是什么啊 也没定义啊

    1. ladeng6666

      2012 年 6 月 29 日 上午 4:10

      这里的body是全局变量,在顶部定义的。

  • jessica

    2012 年 7 月 26 日 上午 6:21

    喜欢你的博客

    1. ladeng6666

      2012 年 7 月 27 日 下午 12:53

      谢谢,欢迎你继续关注我的博客

  • jessica

    2012 年 7 月 26 日 上午 9:58

    我不明白
    body在这里只是一个工厂的概念吗?
    如果说每个刚体有一个对应的对象,那对应的对象是bodyRequest吗?
    还有createDebug()应该是控制刚体显示的,但是我看不出来那句话显示了所有刚体啊

    不好意思啊,我菜鸟,才学as一个月,然后上网看到有引擎,所以好奇想学。

    1. ladeng6666

      2012 年 7 月 27 日 下午 12:51

      createDebug是我自定义的一个函数,实际上绘制刚体对象的是b2DebugDraw类。
      你可以把b2BodyDef和b2PolygonDef看成是body必备元素,你所说的对应的对象是只的body.useData,这个属性用来绑定一个显示对象。

  • jessica

    2012 年 7 月 26 日 上午 10:00

    其实我就是想知道愤怒的小鸟这种游戏,小鸟是一个sprite,但是我怎么让这个小鸟变成一个刚体呢?

    1. ladeng6666

      2012 年 7 月 27 日 下午 12:43

      相信你看过刚体的上衣就知道怎么做了

  • victor

    2012 年 8 月 1 日 上午 3:10

    你好,我想请问一下,那个红色的矩形区域可以被隐藏掉么?

    1. ladeng6666

      2012 年 8 月 1 日 下午 12:49

      你指的是不显示吗?如果是的话,那不绘制b2DebugDraw就可以啦,但是这时候必须要设置body的userdata,具体请参考刚体的上衣——b2BodyDef.userData

  • sky

    2012 年 8 月 7 日 上午 7:45

    你好,拉登兄学习BOX2D有去看懂引擎的代码吗?

    1. ladeng6666

      2012 年 8 月 7 日 上午 9:00

      不用去了解引擎的代码,只要会用就可以,当然如果你用起来易如反掌,可以研究并升级Box2D源代码,呵呵!

  • zzzz

    2012 年 8 月 24 日 下午 11:01

    拉登兄你好,请教你一个问题,引擎中的密度到底有什么作用?我分别将同等大小的2个下落的小球的密度设置为不同的值,可是它们的下落速度还是一样..如果我要实现同样大小尺寸的2个物理同时下落,但要求这2个物体的下落速度不一样该怎么做?谢谢,请你务必回答我这2个问题,再次感谢!!

    1. ladeng6666

      2012 年 8 月 25 日 下午 2:58

      Box2D模拟的是一个真空的环境,记得阿基米德的一个小球和羽毛同时落地吗?下落的速度和质量是没有关系的。如果想让物体下落速度快,可以通过ApplyForce对物体再施加一个向下的速度,具体ApplyForce的用法请参考让刚体听我的——ApplyForce、ApplyImpulse、SetLinearVelocity

      1. zzzz

        2012 年 8 月 26 日 下午 6:34

        感谢拉登兄的回复!!
        只是有一点我还不太明白,就是引擎中物体的密度到底有什么作用?它究竟能改变物体的什么?请再回答我这一个问题,再次感谢!!

        1. ladeng6666

          2012 年 8 月 26 日 下午 9:04

          密度会影响物体的质量,质量越大,物体的惯性越大,因此物体的动量维持的就越久。
          简单的讲,相同体积的静止的刚体上施加相同的力,密度大的移动的较慢,密度小的移动的较快。
          同样的道理,以相同速度移动的同体积刚体,密度小的停下来的比较早,而密度大的物体停下的较晚。
          不知道,我这么解释你能听明白吗?

  • zzzz

    2012 年 8 月 27 日 上午 9:24

    非常感谢!

    1. ladeng6666

      2012 年 8 月 28 日 下午 10:42

      谢谢你的关注!!

  • lanzhipeng

    2012 年 9 月 7 日 上午 9:43

    private function createBody(posX:Number,posY:Number):void
    private function createGround():void

    这两个写鼠标的那个就行了,上来就创建一个刚体虽然设计上没问题,但是以新手的角度来解读的话,他会以为你的最后一句有另外的含义,起始,只不过就是创建一个刚体而已,没有太对必要的!

    1. ladeng6666

      2012 年 9 月 7 日 下午 9:00

      大师哥,我知道错了,以后会注意的!!

  • cantian

    2012 年 10 月 16 日 上午 8:52

    建议把debugDraw等等中文翻译成中文,初学者难懂啊,我觉得比flash里面的类名难懂多了

    1. ladeng6666

      2012 年 10 月 22 日 下午 9:13

      debugDraw等中文翻译成中文?你的意思讲一下debugDraw的用法嘛?

      1. cantian

        2012 年 10 月 23 日 上午 8:56

        不,就是debugDraw等的在这个引擎里面最确切的中文字面意思,不是它的用法

        1. ladeng6666

          2012 年 10 月 23 日 下午 7:53

          Box2D只是一个2D物理引擎,它通过内置的算法,对添加的b2Body刚体模拟物理运动,但是b2Body并不是显示对象,也就是说无法通过addChild添加到舞台上并显示。Box2D中通过b2DebugDraw类,绑定一个Sprite对象,并通过调用它的Graphics的绘图API,绘制出b2Body,让开发者可以调试自己的应用。当然如果要添加自己的MovieClip,可以参考我的教程刚体的上衣——b2BodyDef.userData
          这样解释,你可以明白了吗?至于怎么debugDraw的中文怎么说,随便了,知道自己明白就行。

          1. cantian

            2012 年 10 月 24 日 上午 12:23

            谢谢,感谢你的耐心及时的回答,再追问一个问题,绘制出b2Body刚体与那个Sprite对象是什么关系,b2Body刚体是Sprite对象的子对象吗,那个Sprite对象在舞台上吗(是作为一个空的对象放到舞台上吗,只是我们看不见?)

  • cantian

    2012 年 10 月 23 日 上午 9:06

    我想问一下你这代码是在什么环境下写的,是flash cs还是flash developer

    1. ladeng6666

      2012 年 10 月 23 日 下午 7:55

      我是用Flash Develop写代码,Flash cs IDE的编辑器功能太少了。

  • cantian

    2012 年 10 月 23 日 下午 4:17

    拉登大哥,除了debugDraw其他的都看懂了,谢谢你提供这个好教程,
    请你讲解一下debugDraw的作用,用法,和程序逻辑,最好打个比喻,好理解,
    万分感谢

  • cantian

    2012 年 10 月 24 日 上午 12:40

    今天研究了一天的box2d,对box2d多少理解了一些,多谢你的教程,你的教程发现是网上写的最好的,建议可以出这方面的书,
    我想问下,box2d较成熟的应用有没有,有没有通过它做出来的游戏什么的

    有几个名称我翻译的,你看怎么样(我觉得哪些类和方法最好有个贴切的中文翻译,毕竟我们的母语是中文,中文好理解,我上次看box2d头都大了,相信很多初学者和我一样的感受,今天硬着头皮看下去,才基本上看懂了):
    aabb:轴对齐边界框, 其实就是矩形边界框,表示wold的有效范围
    debugDraw:调试用绘制刚体

  • jessica

    2012 年 11 月 9 日 下午 5:37

    debugDraw.m_drawScale = 30.0;

    求解释 m_drawScale 这个属性的意思

    1. ladeng6666

      2012 年 11 月 11 日 下午 11:04

      请参考这篇文章

  • tank

    2012 年 11 月 19 日 下午 5:21

    非常好的文章,简单明了,排版很清楚!

  • kingBook

    2013 年 2 月 27 日 下午 9:50

    从事as开发快一年了,对box2d一直是心里的一道坎,一直都过不去,在网上查了很多的资料,要么全是英文,要么不清不楚,现在已看了两章,感觉比网上任何一个helloworld例子让人更易于理解,楼主对于每一个提问者都如此耐心回答,相信别人和我也一样别人提出的问题其实我也一样不清楚,可再看作者的解释脑海里是如此的清晰明了,感谢作者如此无私奉献,相信有了你的这一套教程,我box2d一定可以学好.

    1. ladeng6666

      2013 年 2 月 28 日 下午 8:22

      谢谢你的评论,其实我一开始学习box2D时,也是摸不着头脑,官方的教程也很专业,所以自己硬着头皮去研究,然后用傻瓜式的语言重新描述,能给大家带来帮助,我很高兴,也希望你能帮我推广,让更多的网友关注我的教程,谢谢啦!

  • alex

    2013 年 4 月 23 日 下午 2:34

    debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;

    等号右边,中间的那一条 | 是什么意思啊?

    1. ladeng6666

      2013 年 4 月 23 日 下午 8:53

      是或的意思!官方API里有解释

  • Christoper

    2013 年 8 月 13 日 下午 3:15

    This is cool!

  • Suzette

    2013 年 8 月 19 日 下午 7:18

    Cool!

发表评论

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