使用FlashCS6制作cocos2d-x动作脚本的思路整理

前言

最近参加了一个卡牌游戏项目的前期准备工作,工作内容是做一个卡牌游戏的战斗场景demo。其中有不少动作特效动画,比如攻击的时候卡牌需要扭动、被攻击时需要斜后方抖动平移等等。cocos2d-x引擎实现这些动画不是问题,无非是Sprite执行MoveBy、RotateTo、EaseIn、EaseOut等动作极其组合,难点在于动作特效的编辑。作为一个程序猿,我是有自知之明的,动作特效编辑不是我擅长的,这种事情最好交给专业的美术去做。

问题在于,美术用什么工具去编辑这些动画?程序如何去读取?

首先想到的是CocoStudio,但最终放弃了,因为这不是CocoStudio擅长的领域,最直接的,CocoStudio无法实现颜色透明度的渐变。

最理想的工具非Flash莫属,说道做动画,首先想到Flash。但是Flash做出来的动画怎么应用到程序呢?总不能将动画分解,然后一段段用程序翻译吧?

偶然间遇到这篇文章 http://baike.baidu.com/link?url=uZwJfQlmQzF6R88DmJdK9gv2q-L6jMwiIgkIz9YdUNukYnkBt7mVuR64m2LDDiWmLbr_Iq3UYLB5TLG_fsCkp_

突然眼前一亮,救星啊,原来FlashCS5以后的fla文件其实是个ZIP包,所有的帧数据都保持在zip包里面的DOMDocument.xml文件里面。而且,保持Flash的时候,你可以选择*.xfl格式,这样其实就是一个文件夹,DOMDocument.xml就躺在文件夹里面等你。

好啦,基本思路就有了,想办法解析DOMDocument.xml文件,将其翻译为cocos2d-x能读懂的。

PS:实现代码我已经发到github了,地址https://github.com/ctbinzi/FlashCS6ForCocos2d-x

解读DOMDocument.xml文件

在解读DOMDocument.xml之前,我们先了解一下Flash存档的目录结构,如下:

使用FlashCS6制作cocos2d-x动作脚本的思路整理_第1张图片

左侧是Flash的lib库结资源目录构,右侧是该Flash项目的存档目录结构,可以发现,lib库下面的每一个资源都对应一个位于存档文件夹下的LIBRARY目录下面的文件,位图资源对应的是图片文件,目录对应的是同名文件夹,MovieClip对应的是xml文件,且该xml文件完整地描述了该MovieClip的详细信息。当然,在存档目录的根目录位置有一个DOMDocument.xml文件,该文件描述的是该Flash舞台及其相关属性。

好了,了解完Flash存档目录结构和Flash资源的关系后,我们可以开始逐一分析他们了。

首先,我们还是从DOMDocument.xml开始入手,我将该xml文档中一些暂时不太关心的内容去除,并在需要我们着重关心的部位加上注释,记录如下

<DOMDocument frameRate="60"> 
<!-- DOMDocument是该xml文档的根节点,其中我们比较关心的属性只有一个frameRate,该属性值记录的是该Flash的帧频率,FlashCS6的默认值是24-->
     <folders><!-- 该节点下罗列了我们在LIBRARY里面创建的文件夹,其实我们可以不必关心它 -->
          <DOMFolderItem name="folder_effect" itemID="537776ce-000001df" isExpanded="true"/>
     </folders>
     <media><!-- 该节点下罗列了该Flash所用到的图片及其它从外部到了的多媒体资源信息 -->
          <DOMBitmapItem name="8.png" itemID="5313e068-000001f8" sourceExternalFilepath="../Actions/LIBRARY/8.png" sourceLastImported="1392726125" externalFileCRC32="1072798625" externalFileSize="34982" originalCompressionType="lossless" quality="50" href="8.png" bitmapDataHRef="M 1 1393811560.dat" frameRight="4200" frameBottom="3840"/>
		  <!-- 该节点描述了该多媒体资源的相关属性,其中我们比较关心的属性如下:-->
			<!--name	该多媒体资源的名字,即我们在Flash编辑器的库视图里面看到的名字,如果是在文件夹里面的话,其名字会带上文件夹路径-->
			<!--itemID	唯一ID,Flash里面的所有资源都会被分配一个类似这样的唯一ID-->
			<!--href	该资源对应存储目录下的文件相对路径,相对LIBRARY文件夹的路径-->
          <DOMBitmapItem name="effect1.png" itemID="531d709d-000001e6" sourceExternalFilepath="../Actions/LIBRARY/effect1.png" sourceLastImported="1392901873" externalFileCRC32="2070406904" externalFileSize="16942" originalCompressionType="lossless" quality="50" href="effect1.png" bitmapDataHRef="M 2 1394436802.dat" frameRight="3480" frameBottom="3420"/>
          <DOMBitmapItem name="folder_effect/effect2.png" itemID="531e6ce8-000001ee" sourceExternalFilepath="../Actions/LIBRARY/effect2.png" sourceLastImported="1362735664" externalFileCRC32="1477998738" externalFileSize="36159" originalCompressionType="lossless" quality="50" href="folder_effect/effect2.png" bitmapDataHRef="M 3 1394500443.dat" frameRight="8000" frameBottom="5200"/>
     </media>
     <symbols><!-- 该节点下罗列了该Flash所拥有的MovieClip信息,每一个MovieClip对应一个xml文档,存放于LIBRARY目录下面 -->
          <Include href="1.xml" loadImmediate="false" itemID="5332958a-000001da" lastModified="1395884060"/>
		  <!-- 该节点描述了一个MovieClip的相关属性,其中我们比较关系的属性如下:-->
			<!--href	该资源对应存储目录下的文件相对路径,相对LIBRARY文件夹的路径-->
			<!--itemID	唯一ID,Flash里面的所有资源都会被分配一个类似这样的唯一ID-->
          <Include href="2.xml" loadImmediate="false" itemID="531e636b-000001db" lastModified="1395884063"/>
          <Include href="Card1.xml" loadImmediate="false" itemID="5313e070-000001fa" lastModified="1395884065"/>
          <Include href="effect1.xml" itemID="533295a5-000001de" lastModified="1395912879"/>
          <Include href="effect2.xml" itemID="533295a2-000001dd" lastModified="1395914886"/>
          <Include href="folder_effect/effect3.xml" itemID="5333f886-00000213" lastModified="1395914979"/>
     </symbols>
		... ...
</DOMDocument>

需要特别说明的是,<timelines>节点及其子节点我没有做任何说明,因为我们这个项目不打算把动画直接做在舞台上。主要原因是为了方便管理,我们把所有动画都做到了MovieClip里面。从上述描述信息中我们可以看到,在这个xml文档中,我们比较关心的内容主要是图片资源信息和MovieClip信息,下面我们需要做的事情就是逐一解析MovieClip。

从上述内容我们知道每一个MovieClip在LIBRARY目录下面都有一个对应的xml文档来存储其详细信息,下面,我们还是按照DOMDocument.xml分析方法,分析一个MovieClip文档。

<DOMSymbolItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ns.adobe.com/xfl/2008/" name="test" itemID="5377877f-000001fc" lastModified="1400342648" lastUniqueIdentifier="1">
  <timeline>
    <DOMTimeline name="test"><!--时间轴,每个MovieClip有且只有一个,不必关心-->
      <layers>
        <DOMLayer name="layer1" color="#9933CC" autoNamed="false">
		<!-- 层,对应Flash编辑器里面的的层,每个层可以添加多个关键帧,每个关键帧对应一个DOMFrame节点 -->
          <frames>
            <DOMFrame index="0" duration="9" tweenType="motion" motionTweenSnap="true" keyMode="22017" acceleration="-100" soundName="test.mp3">
			<!-- 记录关键帧信息,关键帧即如上图所示,带有实心点的帧。我们比较关系的属性有如下:-->
				<!-- index			帧索序号,从0开始-->
				<!-- duration		该关键帧持续帧数,即从改帧开始到下一个关键帧之间间隔的帧数 -->
				<!-- tweenType		渐变动画类型,在我们这个项目中只会用到传统补间动画,对应值为motion-->
				<!-- acceleration	缓动效果,比较有意思的是,该值和我们在Flash编辑器里面设置的值符号刚好相反-->
				<!-- soundName		声音,其值对应DOMDocument.xml文档里面记录的名字-->
              <SoundEnvelope>
                <SoundEnvelopePoint level0="32768" level1="32768"/>
				<!--声音属性,level0和level1分别对应了左声道和右声道音量值[0~32768]-->
              </SoundEnvelope>
              <elements>
			  <!--记录该帧放置内容,我们可以在一个关键帧放入影片剪辑、图片、声音等信息,这些信息都将一一记录如下-->
                <DOMSymbolInstance libraryItemName="1" centerPoint3DX="-159.95" centerPoint3DY="-52">
				<!--每一个被放入该帧的MovieClip都将对应一个该节点,其中我们比较关系的属性是-->
					<!-- libraryItemName	该属性值记录了该MovieClip的名字,对应DOMDocument.xml文档里面记录的名字-->
                  <matrix>
				  <!--该节点记录了该MovieClip在该帧时的位置信息,通过选择矩阵的方式记录,包括了坐标位置、旋转角度、缩放等信息-->
                    <Matrix a="0.30902099609375" b="-0.9510498046875" c="0.9510498046875" d="0.30902099609375" tx="-77.8" ty="-25.3"/>
                  </matrix>
                  <transformationPoint>
                    <Point y="-86.4"/>
                  </transformationPoint>
                  <color>
				  <!--该节点记录了该MovieClip在该帧时的颜色信息,主要包括argb是个颜色通道的值,Multiplier是百分比值[0~1],Offset是相对值[-255~255]]-->
                    <Color alphaMultiplier="0.4296875" redMultiplier="0.83984375" blueMultiplier="0.87890625" greenMultiplier="0.87109375" alphaOffset="14" redOffset="8" blueOffset="29" greenOffset="15"/>
                  </color>
                </DOMSymbolInstance>
                <DOMBitmapInstance libraryItemName="8.png">
				<!--每一个被放入该帧的位图都将对应一个该节点,其中我们比较关系的属性是-->
					<!-- libraryItemName	该属性值记录了该位图的名字,对应DOMDocument.xml文档里面记录的名字-->
                  <matrix>
                    <Matrix tx="-299.95" ty="57.15"/>
                  </matrix>
                </DOMBitmapInstance>
              </elements>
            </DOMFrame>
          </frames>
        </DOMLayer>
      </layers>
    </DOMTimeline>
  </timeline>
</DOMSymbolItem>

需要注意的是,为了列举尽可能多的情况,并控制文档不会过长,我对原始文档做了调整,可能无法被FlashPro正常解析,但不影响我们理解。

从上述解析文档可以看出,需要我们着重关心的是<DOMFrame>节点属性,以及<SoundEnvelope>、<DOMSymbolInstance>、<DOMBitmapInstance>节点内容。此外,我们需要理解在Flash里面,动画师由关键帧组成的,即关键帧在时间上的延续,以及关键帧到下一个关键帧的渐变过程。

另外,Flash的舞台其实也是一个MovieClip,也就是说,如果我们直接在Flash舞台上放置了元件,或是在舞台的时间轴上添加了关键帧,那么在DOMDocument.xml文档里面的内容也将跟上述解析内容类似,一样对待即可。

你可能感兴趣的:(使用FlashCS6制作cocos2d-x动作脚本的思路整理)