PhysicsEditor+Starling+Nape的一个小例子

为了响应来自TexturePacker作者大方赠送的PhysicsEditor(以下简称PE)的license,我花了一点时间写了一个小东西,创建的过程记录在此,以备后用。

Demo | Source

PE使用起来非常方便,找到你要作为刚体的png图片,在PE中Add Sprite功能将其添加进来,具体的部分在Devon O. Wolfgang的Blog中有记述,比如我导入了下面的舵盘png图片。
 
虽然PE支持手动打点描边,嗯……反正我是不会自己去打点,所以它的Sharp Tracer功能是它第一个亮点(话说没有这个的话就真的不用它了)。
如果你发现由于你的位图素材有描边,发光或者阴影效果影响了Tracer捕捉外缘,可以通过调整公差值(tolerance,话说这是啥啊…),以及透明阀值(Alpha threshold),来忽略不必要的毛刺。

调整后点少了,圆润了一些,不过这样貌似会使刚体不太瓷实,我在实测中会发现刚体在某些高速撞击下被击穿的情况。
下面还有一件需要做的是,设置锚点居中。可以通过简单的将Relative设置为0.5来达成。

下面到了让我卡壳片刻的地方,直接选择Nape(AS3),导出的as文件和最新版本的Nape(2.0.12.)中无法使用,具体原因如下所述(源引自Devon O. Wolfgang的Blog):

 This is because the Nape Physics API has been updated since the last release PhysicsEditor (I’m sure it’s hard keeping up to date when supporting all those freaking engines). Thankfully, Andreas Löw has made it incredibly easy to keep the exporters up to date ourselves. Go to the installation directory of PhysicsEditor and find the ‘exporters’ directory. Browse into that then go down and move into the ‘nape-as3′ directory. Inside there, you’ll see a ‘nape.as’ file. Open that in a text or code editor and every place you see ‘cbType =’, change it to ‘cbTypes.add()’.

而做出这样的改变原因如下:

CBTypes are short for Call Back Types. You can create your own call back types and apply them to physics bodies so that interactions will have different results. For example, a collision between two gears may play a different sound than a collision between a gear and the ground. In previous versions of Nape each body could only have a single call back type applied. Now, however, call back types are added to a list and you can have several on a single body. For this basic demo we won’t bother with any cbTypes, but, again, without making these changes to the export, your final project will be filled with errors.

Devon还特意提示说:

NOTE: by the time you read this, this discrepancy may be fixed and none of this may be necessary. I’m currently using the 1.0.9 version of PhysicsEditor.

Unfortunately,我使用的1.0.10版本仍然未修复这个问题,不过Nape方面做出了积极的更新,它们更新了对应PE的模版,可以在这里下载的zip文件中找到对应的PE exporter包,将其复制并粘贴到PE安装路径对应的文件夹里面,
例如:/Applications/PhysicsEditor.app/Contents/Resources/nape-as3

这个exporter模版已经完整地修复了刚刚讨论的cbTypes的问题,只有一处微不足道的不足,是个变量命名重复的警告,我已经修改后放在这里了,覆盖后记得重启PE。

可以通过这个细节看到,PE是按照不同引擎的刚体描述办法,利用其对应的语言描述刚体形状的,所以面对十几个在发展的引擎或框架随时会发生结构调整的情况下,难免会出现以上遇到的问题。

现在我有了一个描述刚体的.as文件了(当然如果你重命名它或者改变路径时需要做对应的调整),在项目中使用它时,是通过调用它的静态函数createBody来实现的,例如我在创建这个舵盘时的代码如下:

1
2
3
4
5
6
7
var gpBody:Body = GrassBallData.createBody("goalPoint");  
gpBody.userData.name = "gp";
gpBody.allowMovement = false;
gpBody.allowRotation = true;
gpBody.position.setxy(130,130);
gpBody.userData.graphic = gp;
gpBody.space = mSpace;

其中GrassBallData为用PE导出的描述类名。如果想对创建的刚体做材质描述,需要向这个类注册对应的材质实例,代码如下:

1
2
var ma:Material = new Material(0.1,1,1,2.5,1);  
GrassBallData.registerMaterial("glass",ma);

并修改对应GrassBallData类中创建刚体时使用材料的指定部分代码:

1
2
3
mat = material("glass");  
filt = filter("default");
prop = fprop("default");

由于我会附上源码,所以其他部分不再赘述(本身也很简单)。值得详细说明的部分是,如何为Nape的刚体注册互动监听。这里Nape做的,嗯,有点麻烦,不知道是不是刚体的世界都是这么不明觉厉。以本段中提到的代码为例,想要响应球撞击到舵盘时候的操作,步骤如下:
1 创建一个回调响应类型:

1
private var gpCollisionType:CbType=new CbType();  

2 创建一个互动监听器,并注册到空间:

1
2
3
4
5
6
interactionListener=new InteractionListener(CbEvent.BEGIN,  
InteractionType.COLLISION,
gpCollisionType,
ballCollisionType,
ballToWall);
mSpace.listeners.add(interactionListener);

3 编写处理事件的函数:

1
2
3
4
5
6
7
8
private function ballToWall(collision:InteractionCallback):void {  
var bd1:Body = collision.int1 as Body;
var bd2:Body = collision.int2 as Body;
if(bd1.userData.name == "gp" ||bd2.userData.name == "gp" )
{
//do something you want on action.
}
}

4 将回调响应类型附加到对应的刚体。

1
gpBody.cbTypes.add(gpCollisionType);  

以上步骤缺一不可,图片资源均来源自网络。

资源:

PhysicsEditor  Tutorials
Starling, Nape Physics, and PhysicsEditor
Nape Physics Engine