运行时创建多边形刚体

作者: ladeng6666 分类: Box2D 发布时间: 2012-08-01 14:40 阅读: 8,496

学习了信手绘制线条刚体,你有没有想过信手绘制多边形刚体呢?”当然了,你不是在上一篇教程中说过了吗?快快说来!!”
是的,正如我说说的,这是重力大师里可以绘制的对象之一。在之前的Box2D多边形刚体教程中。我们学会了用组合法和原生法创建多边形。谈到运行时创建多边形刚体,你会选择哪种方法呢?如果是原生法,恭喜你,我们想到一块去了。借一步讲话,我给你细细道来。

原生法绘制多边形刚体

还记得在信手绘制线条刚体中创建的那些线段吗?而且我用红色圆点标示了他们的坐标。把这些点传递给b2Shape的SetAsVector方法就完成了多边形的绘制,简单吧!(如果你不知道如何用原生法创建多边形,请查看“Box2D多边形刚体”)。效果如下,同样请不要交叉绘制,而且不要逆时针绘制。

完整代码和注释如下:

多画几个刚体,慢慢你会发现。在绘制凹多边形时,刚体的胖子出现了很多错误的现象,甚至穿过了其他的对象。这是由Box2D引擎本身的算法引起的。Box2D的碰撞检测算法是基于凸多边形的,所以对于凹多边形,会出现很多意想不到的结果。

这条路是行不通了,只好选择另一条路了:组合法。

组合法创建刚体

用组合发创建刚体,就是不管刚体是凹多边形还是凸多边形,把它分成多个凸多边形,然后组合成一个整体。

你可能会问:“可谁知道怎么分啊?”

问的好,Antoan Angelov就知道。由他开发的b2Separator类可以根据b2Shape顶点,把它分成一个个凸多边形,然后用组合法组成复杂的多边形刚体。b2Separator主要有下面两个函数:

Separate

Separator方法用来将verticeVec中的顶点分成多个小的凸多边形,并赋值给fixtrueDef,创建body多边形刚体。

每个参数说明如下:

  • body:多边形刚体对象
  • fixtureDef:fixture需求对象
  • verticeVec:存储多边形所顶点的Vector数组
  • scale:Box2D模拟时的缩放比例,这个值与b2DebugDraw中的SetDrawScale的参数值是一样的。

Validate

Validate的功能是检测多边形的刚体是否符合创建的标准,在不符合标准时,返回不符合标准的原因。

每个参数说明如下:

  • verticeVec:存储多边形所顶点的Vector数组

返回值类型有下面几种:

  • 0:顶点符合绘制多边形的标准
  • 1:顶点连接的线段之间有交叉
  • 2:顶点的顺序非顺时针绘制
  • 3:出现1和2两种错误

只有返回值为0时,才可以用Separator方法创建多边形。

了解了b2Separator之后,我们用组合法完成了多边形的绘制,效果如下,点击并拖动鼠标绘制多边形。

效果还不错哦。完整的代码和注释如下:

值得一提的是,因为非顺时针顺序的顶点是无法创建多边形的,所以在validate检测顶点返回2之后,调用verticesList.reverse()方法,反转顶点的顺序。这样用户不管顺时针还是逆时针都可以绘制出刚体来。

上面两个示例中,都用到了LDEasyBox2D,这是我写的一个静态类,简化了刚体创建的过程,如果你不熟悉,请参考我的教程

源代码下载

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

15条评论
  • wssmrw

    2012 年 8 月 3 日 上午 5:48

    不错不错,昨天被折腾死了,我说怎么画个圆不受世界控制

    1. ladeng6666

      2012 年 8 月 4 日 上午 2:59

      只要我的教程对你有帮助就好了!

  • 大谷Spitzer

    2012 年 8 月 9 日 下午 8:30

    碉堡了!
    PS:有没有办法可以把人工绘制的矩形组成的地图元件让Box2D自动生成刚体?

  • sky

    2012 年 9 月 10 日 下午 10:06

    酷~
    这么一来就弥补了凸多边形算法的不足!

  • JaoYE

    2012 年 11 月 26 日 下午 6:27

    求指教
    import Box2DSeparator.b2Separator;
    这个东西在什么里 我的里面没有这个啊

    1. ladeng6666

      2012 年 11 月 26 日 下午 8:21

      这个类是外国高手写的类库,不是Box2D默认的类,可以在我的源文件中下载到。

  • 阿柑

    2012 年 12 月 11 日 下午 5:37

    你好,拉登大师,我想请教1下,怎么可以改变一个已经实例化的刚体大小呢?

    1. ladeng6666

      2012 年 12 月 12 日 下午 9:07

      谢谢你的关注和提问,我会在稍后的教程中讲到这个问题,思路是把shape删掉后重新绘制,你想看到什么样的示例呢?

      1. 阿柑

        2012 年 12 月 13 日 下午 3:09

        shape删除掉再重新绘制不会突然造成一个外力么?实例做一个收缩放大的心脏在物理空间跳动如何呢?还有拉登大师,水的效果又怎么做呢?我想到的是是,1个水珠是1个圆形刚体,然后皮肤用滤镜模糊,但不知道效率如何。还有皮球的刚体又怎么实现呢。就像用手压1个皮球,会有1部分陷进去,松手又弹回来。。。哎呀,BOX2D想问好多问题啊~~~~继续期待您的教程~~~~

        1. ladeng6666

          2012 年 12 月 13 日 下午 9:19

          你的问题好多啊,继续关注我的网站吧,我会继续写更多的Box2D教程的,你的问题慢慢都会出教程的!!

  • Yorhom

    2014 年 7 月 28 日 下午 6:00

    如果多边形是由2个三角形构成,也就是说构造多边形的数组是[{x:0, y:50}, {x:50, y:0}, {x:100, y:50}, {x:150, y:0}, {x:200, y:50}],那么b2Separator就会判断出现线条交叉,创建不出刚体,请问这个问题怎么解决?

    另外,我觉得新的评论系统看起来没有以前的好,我觉得以前那种嵌套模式阅读评论比较容易

    1. ladeng6666

      2014 年 7 月 28 日 下午 6:26

      如果是有多个形状构成的话,建议你用createFixture()或createFixture2()创建多个b2Fixture对象来组合成一个刚体!
      另外,评论系统也改回来了,是不是你想要的效果? [嘻嘻]

      1. Yorhom

        2014 年 7 月 28 日 下午 6:30

        是的,这么一改,评论框就漂亮多了 [哈哈]

        1. ladeng6666

          2014 年 7 月 28 日 下午 6:56

          对了,有没有感觉我的网站速度快了一点?

          1. Yorhom

            2014 年 7 月 28 日 下午 6:59

            感觉访问速度一直都很快啊

发表评论

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