用 DragonBones for Cocos2d-x 实现帧动画
本文所使用的 Cocos2d-x 和 Cocos2d-html5 版本均为 2.2.2
美术组对骨骼动画提出了一个需求,希望能用 DragonBones 实现定格效果,而不是每帧都自动产生补间。
经过一翻搜索,我在这里找到了一个方法,只需要在骨骼的关键帧上使用^
标签就可以取消骨骼动画的补间。实际上 DragonBones 的 wiki 上就有这么一行说明,被我略过了。
疑问
不过,虽然这个方法确实能在 DragonBones 插件的预览窗中看到定格动画的效果,但导出到 Cocos2d-x 或 Cocos2d-html5 中时,依然还是有补间动画。
阅读了 Cocos2d-html5 的源码后,我发现了问题所在:
/extensions/CocoStudio/Armatrue/utils/CCDataReaderHelper.js
ccs.CONST_A_TWEEN_FRAME = "tweenFrame"; ccs.DataReaderHelper.decodeFrame = function (frameXML,parentFrameXml,boneData,dataInfo) { // ... var isTween = frameXML.getAttribute(ccs.CONST_A_TWEEN_FRAME) || true; frameData.isTween = Boolean(isTween); // ... }
当解析 DragonBones 导出的 xml 文件时,判断是否补间,它读的是tweenFrame
字段,然而 xml 没有这个字段:
<f x="116.45" y="-65.55" cocos2d_x="-18.2" cocos2d_y="-71.5" kX="0" kY="0" cX="1" cY="1" pX="134.65" pY="5.95" z="12" dI="0" twE="NaN" dr="5"/>
DragonBones 使用的则是 twE 来表达补间缓动,一般情况下是 -1 到 +1,没有补间时为NaN
。
此外,这段程序有一处不明显的逻辑BUG。即使 xml 存在 tweenFrame,且为 "0" 时:
Boolean("0")
仍然为true
,于是这成了永真式。
这是 javascript 的一个坑:
"0" == false
Boolean(0) == false
Boolean("") == false
Boolean("0") == true
Boolean("false") == true
修改插件
知道问题的所在后,从何改起?对于 cocos2d-x / cocos2d-html5 为何不读 twE 而是读 tweenFrame 我的了解不多,或许是为了兼容 CocoStudio。
若是要改 cocos2d-html5 去读 twE 字段,而 cocos2d-x 那边的 cpp 代码也要一起变动,代价有点大。所以我决定修改DragonBones for cocos2d-x插件,让它输出 tweenFrame 字段:
<f x="116.45" y="-65.55" cocos2d_x="-18.2" cocos2d_y="-71.5" kX="0" kY="0" cX="1" cY="1" pX="134.65" pY="5.95" z="12" dI="0" twE="NaN" tweenFrame="0" dr="5"/>
但由于上面的逻辑BUG,导致Boolean("0")==true
只好连 cocos2d-html5 的源码一并修改,稍后再向官方提交一个issue。
var isTween = frameXML.getAttribute(ccs.CONST_A_TWEEN_FRAME) || true; frameData.isTween = (isTween != "0" && isTween != "false");
翻阅了一下 cpp 的代码,它是用 tinyxml 的 QueryBoolValue 来读 tweenFrame 字段,"0" 和 "false" 都能正确解析为false
。
由于以前经常把玩 Flash,所以对 DragonBones for cocos2d-x 的插件修改较为顺利。在这里就不多说了,直接提供下载地址:
插件下载
https://github.com/mutoo/dragonbones-for-cocos2d-x/raw/master/build/DragonBonesDesignPanel.zxp
其它
若是要使^
与 帧事件@event_name
和 子骨骼动作#mov_name
一起生效,可以用|
将各个部分隔开,但^
必须放在第一个,如^|#fire
。
在 Cocos2d-x 中使用 DragonBones
开发小组准备在下一个游戏中使用骨骼动画,这段时间对相关的技术进行了一些尝试,在这里做一个杂记。
实验环境
操作系统
技术组 Mac OS X 10.9 美术组 Windows 7
游戏引擎
cocos2d-x 2.2.2 + jsb cocos2d-html5-2.2.2
CocoStudio Animation Editor
Q: 为什么不用 CocoStudio Animation Editor?
A: 经过一个星期的尝试,美术组觉得这是一个非常呆板的工具。作为一个开源工具来说,CocoStudio 还很年轻。基本的功能虽然可以实现,但是操作异常繁琐。另外一点就是 CocoStudio 目前只支持 Windows 系统。而且根据实践,它并不支持子骨骼动画。
DragonBones
DragonBones 是一款 Flash 骨骼动画插件,在页游界非常流行。可以生成骨骼数据包,并导入到其它引擎使用。zengrong大牛把 DragonBones 2.2 进行修改后可以很好地支持 Cocos2d-x,极大地方便了骨骼动画的制作。
一些真相
-
导出数据请使用 Zip(XML+PLIST+PNG)
其中 XML 是骨骼及动画配置,还包括有纹理数据;
PLIST 是纹理数据,可独立配合 PNG 使用,相当于一般素材。 -
循环动画的最后一帧需要重复第一帧数据
cocos2d-x 在实现循环动画的时候,并不像 DragonBones 那么智能,解析动画数据的时候,没有处理最后一帧的循环补间,只是生硬的跳回第一帧。所以需要手工将这第一帧补到动画最后。由于产生的停顿感,可以借由增加各关键帧的长度来掩饰。
cocos2d-html5 的源码中,在解析骨骼数据时有意将最后一帧进行复制,不知是手误还是有其它用意。如果为了使动画产生没有延时感的循环,应该复制第一帧才是。
-
cocos2d-x 支持 DragonBones 的帧事件(evt)
在骨骼的关键帧上标记 @event_name 可以向 cocos2d-x 发出事件消息;
在 cocos2d-html5 中使用armature.getAnimation().setFrameEventCallFunc(this.onFrameEvent,this);
进行侦听。
相关用法自行参考 cocos2d-x 测试用例。 -
cocos2d-x 不支持 DragonBones 的声音事件
-
DragonBones 的 mov 事件可用于子骨骼动作的切换
在骨骼的关键帧上使用 #movement_name 可以向子骨骼切换至 movement_name 指定的动作。
-
Flash 的帧数 与 游戏的帧数 的帧数不一致时,需要用
armature.getAnimation().setSpeedScale();
进行调整通常缩放系数为 (Flash的帧数)/(游戏的帧数)。
-
在 Flash 中管理素材的时候如果要分组,请把子骨骼放在最外层,不然会遇到一些问题
插件在转换素材和骨骼时使用了不同的命名规则,素材是
parts-image
而骨骼是parts/bone
;
这会导致导出的子骨骼找不到纹理。 -
尽量不要使用斜切变换,导出后看到的效果与 DragonBones 预览严重不一致
Cocosc2d-x 与 Cocos2d-html5(canvas) 与 Cocos2d-html5(webgl) 使用的插值算法都不一样。
-
Cocos2d-x 的 tint(染色)机制与 Flash 并不一样
Cocos2d-x 的染色并不能真的给精灵上色,
sprite.setColor(cc.white)
相当于白光照在精灵上,效果也就是精灵原本是什么颜色,那么它现在还是什么颜色。sprite.setColor(cc.black)
相当于把灯关掉,所以精灵变黑色。
相关文章:
http://digitallybold.com/314/cocos2d-additive-sprite-color-tinting
http://lukehatcher.com/post/449164972/coloring-sprites-with-cocos2d-iphone -
DragonBones 可以在骨骼关键帧设置缓动,或者使用
^
标签取消补间,但 Cocos2d-x 没能正确解析这个属性在 CCDataReaderHelper.js 中的 decodeFrame 方法有这么一行
var isTween = frameXML.getAttribute(ccs.CONST_A_TWEEN_FRAME) || true;
实际上 DragonBones for Cocos2d-x 不并输出 "tweenFrame" 属性;
若要实现定帧动画,需要修改 Cocos2d-x 源码,或者修改 DragonBones 扩展。 -
如果你使用 Mac OS X 10.9 + Adobe Flash CS5.5 请下载Adobe Extension Manager 5.5.3 更新补丁
AdobeExtensionManager_5_5_3_mul_AdobeUpdate.dmg
不然你就装不上 DragonBones 插件。
相关资源
DragonBones 官方教程(美术组必看)
DragonBones v2.0 xml格式解释(该版本较接近2.2)