用MarchingSquares实现自定义刚体形状

作者: ladeng6666 分类: Nape 发布时间: 2013-06-01 15:28 阅读: 9,761

今天我们来学习一个叫做MatchingSquares的新东东。它的功能是在运行时,通过一个名为run的静态函数,动态生成自定义形状的刚体。

是不是有点胡涂?run什么啊?别急,听我细细向你道来。

我们知道,在Nape中,处理标准圆形Circle的形状都被归为多边形Polygon,而要创建一个Polygon,必须指定多边形的每一个顶点。Nape这样做肯定是以偏概全了,因为还有很多形状是规则的、简单的,例如半圆形和椭圆形。我们可以利用高中时学习的几何公式计算出他们的轮廓,但是如果要指定这些形状的顶点,就不是一件容易的事情了。

今天我要将的MarchingSquares类就可以帮我们解决这个问题,结合这些规则的、简单的形状公式,在运行时创建自定义的形状。

实际上MarchingSquare是一个边缘检测算法,不过我没有安下心来,把这个算法研究明白,如果有兴趣的话,可以参考天地会译林军兄弟翻译的emanueleferonato的这篇文章http://bbs.9ria.com/thread-176310-1-1.html,当然,不看也没关系。

Nape中的MarchingSquares类很简单,只有一个静态函数run,不过这对绘制那些简单的形状来说,已经足够了(当然MarchingSquares能做的不只这些)。下面是这个run方法的结构:

“哇!一大堆的参数,这些单词都不认识!”是不是感觉刚才的窃喜有点太早了。没事儿,我们来一起看看这些参数。

  •  iso:IsoFunctionDef:这是run函数的核心部份,也是我们定义刚体形状的地方。在官方API中这个参数是IsoFunctionDef类型,不过这是针对Haxe语言的,针对Flash中这个iso是IsoFunction类型的。

这里的IsoFunction并不是一个具体的类,而是接口(注意到没,他是”I”开头的,Flash中接口类都是以”I”开头的)。它的结构如下:

我们需要新建一个类,应用这个IsoFunction接口,在iso函数中编写刚体形状公式。然将这个类的实例化对象赋值给iso参数。

  • bounds:AABB:表示舞台中的某个区域,类似于AS3中的Rectangle类。这个区域和iso函数中遍历的区域相同
  • cellsize:Vec2:分解bounds区域的单元格尺寸,这个尺寸越小,iso函数仿真出来的形状越逼真,相应的CPU消耗也越大
  • quality:Int = 2:在单元格边缘应用递归进行插值运算的次数,当iso遍历的单元格尺寸较大时,可以通过增加整个值来提高边缘的精确度。
  • subgrid:Vec2 = null: 设置此参数后,bounds区域首先以subgrid的尺寸分割,然后分割后的单元格再以cellssize的尺寸进行分割。所以subgrid的尺寸一定要比cellsize的尺寸大。
  • combine:Bool = true: 当这个参数为true时,每个单元格里分割出来的多边形,会组合成一个大的多边形。
  • output:GeomPolyList = null:设置整个参数后,生成的GeomPolyList会自动添加到(通过GeomPolyList的add函数)output中,而不会新建一个GeomPolyList对象。得到这个GeomPolyList之后,根据我们学过的GeomPoly方法创建多边形。http://www.ladeng6666.com/blog/2013/01/28/draw-nape-polygons-with-geompoly/

还是一头雾水吧,别急,跟上!

首先从第2个AABB参数开始,我们需要为run方法指定一个要计算的区域(如下图中的黑色方框),就好像我们要分析这一块的每个像素一样,不过run方法不会一个一个,一行一行的去分析每个像素,这个距离由第3个参数cellsize指定。

cellsize指定run方法在AABB区域遍历计算的间距,如下图,每个单元格的尺寸是10×10,那么run方法会以10个像素为间隔,检查每个像素是否在目标形状内,也就是图中的蓝色圆形。

Matchsquare

回过头来在看iso参数。iso的参数必须是一个应用IsoFunction的类,同时这类中也有一个名为iso的函数,这个函数有两个参数x和y,这里的x、y即run函数在AABB中遍历的坐标。如上图举例,那么x的取值会是30、40、50、60、70、90、100,y值也是类似的。

另外iso函数还会返回一个Number值,这个返回值小于0,表示该点在形状内部,属于刚体一部份,大于0表示该点在形状外部,不在刚体范围内。

明白了前3个参数,后面的看参数说明就能明白了,如果还是不明白的话,就看看下面的示例吧。

下面的示例中,试着调整右上角对应的相关选项,看看每个参数的作用,以及不同的设置实现的不同效果。

Sorry, either Adobe flash is not installed or you do not have it enabled

完整的代码如下:

 

掌握了MarchingSquares的用法之后,你可以在iso函数添加任意形状的公式,如椭圆、五角星等等。当然MarchingSquares的功能不只这么简单,下一节,我要教你用MarchingSquares动态的加载图像,并创建对应形状的刚体!

点击下载源文件

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

12条评论
  • lanzhipeng

    2013 年 6 月 1 日 下午 4:54

    哎呦不错哦!~又有新东西学了啊!~

  • DreamofC

    2013 年 6 月 7 日 下午 5:27

    百忙之中也要来捧拉登的场啊,哈哈

    1. ladeng6666

      2013 年 6 月 7 日 下午 10:39

      谢谢兄弟捧场!

  • Jerry

    2013 年 7 月 22 日 下午 3:50

    不太明白那个内部形状,

  • Pingback: 基于图像创建多边形Nape刚体 « Ladeng6666
  • RainYuTian

    2015 年 6 月 2 日 上午 11:05

    拉登大叔,我想问一下怎么样才能固定body不让它旋转呢?

  • RainYuTian

    2015 年 6 月 2 日 上午 11:07

    嘛!刚刚找到方法了,谢谢你的教程,十分有用!

    1. ladeng6666

      2015 年 6 月 2 日 下午 7:40

      感谢支持,我会努力为大家写出更多物理游戏开发相关的教程!

      1. RainYuTian

        2015 年 6 月 6 日 下午 9:56

        在Node里,liveBodies是活动的Body才会在列表里。那KINEMATIC类型,怎么才能去激活它呢?让它也在liveBodies的列表里。ladeng大叔的QQ能不能告诉我,我有好多问题。

        1. ladeng6666

          2015 年 6 月 6 日 下午 10:49

          我的QQ:328800655,欢迎和我交流

  • 内涵段子

    2015 年 10 月 11 日 下午 3:37

    太厉害啦!值得我们学习

  • 邪恶内涵图片

    2015 年 10 月 18 日 上午 11:27

    我来留下脚印

发表评论

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