将SWF文件用作资源打包

使用Flash开发网页游戏少不了与各种美术资源打交道。对于静态资源的那就是各种图片,对于会动的资源可以考虑直接做成swf。制作成swf的美术资源又可以分为两种:一种是直接将关键帧罗列在主时间轴上,那么当程序使用Loader类加载完swf文件后,就可以直接addChild在显示列表上;另一种是将美术资源封装成影片剪辑(MovieClip),并为AS3导出类,这样在程序中可以用类似new XXX的方式将美术资源创建出来。

弊端
然而,这种使用swf的方式有一个非常大的弊端,就是会重复创建位图,导致内存浪费。比如,你使用Flash CS5制作了一个swf文件,在主时间轴上放置了一个图片。那么,当你每次使用Loader加载这个swf文件的时候,实际上会创建出很多个位图实例,非常占用内存。Flash自身有一个BitmapData类是用来处理这种情况的,具体用法就是多个DisplayObject共用一个BitmapData,做到位图资源共享,减少内存开销。但是,你需要手动指定哪几个DisplayObject需要共用BitmapData。像上述这种情况,两次加载同一个swf文件,Flash并不会自动为我们共享使用其中的位图资源。

 多次装载一个含有桌面壁纸图片的swf文件后,内存的使用情况

Flash的这种做法可以理解,毕竟Adobe认为绝大多数Flash中使用的美术资源都是矢量图而不是位图。但是,对于页游来说,基本上所有的美术资源都是位图序列帧动画。比如一个场景中有10个模型相同的玩家角色,如果存在10份序列帧动画的位图副本,那是巨大的浪费。

一种解决方案
一种解决方案就是使用自己定制的类实现动画的播放,而不是使用MovieClip。这样,我们可以确保同一个位图在内存中仅存在一份副本,也就是一个BitmapData。因此,swf在这里仅用作资源打包。

使用Flash CS,在库中为相应的图片导出AS3链接,这样我们就能通过 new TestBmpClass() 的方式在程序中创建对应的美术资源

为什么使用swf而不是自定义的文件格式打包图片资源呢?原因有两点,其一是对于带alpha通道的图片来说swf的压缩体积更小,其二是Flash虚拟机解析swf文件的速度比我们自己解析自定义格式文件的速度来的快。

公司目前使用的是一种自有的图片格式,这种格式能够对bmp图进行无损压缩,不过其体积远大于jpeg+alpha通道,解压的速度也比较缓慢(因为没有avm2虚拟机的内部支持)。我的任务是:a)将公司的动画图片转化为swf文件,b)为swf库中的每个图片生成as3链接。

二进制拼装SWF文件
要批量地将一堆bmp图片转换为swf文件,有两种做法。其一是使用Flash CS自带的批处理脚本jsfl,其二是直接通过拼装二进制文件拼出swf。由于需要批量转换大量的美术资源,直接拼二进制文件的方式效率较高,所以我采用后者。

swf的文件格式Adobe已经对外开放,可以参见 SwfFileFormat.pdf

简单地说,swf文件是以 标签-文件块(tag file) 的形式组织起来的。每个标签文件的文件头标识了当前文件块的长度,以及是什么类型的文件块。比如,Flash中的每一帧对应着一个ShowFrame文件块,而每个AS3类则对应着一个DoABC文件块。我所需要拼装的swf文件有着如下的结构:

每个标签文件的含义由它的名字就可以大致猜出。其中白色的标签是必须的,橙色的标签是为了导出AS3类而添加的,蓝色的标签是为了放置在场景中而添加的。由于我们只需要swf中的BitmapData,因此图片并不需要放置在场景中。蓝色标签的加入实际上会增加文件大小,降低解析速度。不过,这样的swf文件在双击点开后就是一片空白,并没有预览。因此,可以考虑分别导出preview版和release版的swf文件。其中preview版在双击打开时可以预览动画,而真正发行的则是没有蓝色标签的release版。

另一个需要注意的地方是,即时不需要将图片放置在场景中显示,也需要ShowFrame标签,否则Flash虚拟机会一直卡在那里。

为AS3导出类
在swf中的图片资源并不能直接使用,需要为AS3导出链接。也就是说,需要为每个图片生成他们对应的AS3类。导出的类需要继承自flash.display.BitmapData,同时我们还可以把自己需要的字段(例如centerX,centerY)添加到类中。

在转换的过程中,我们可能还需要记录一些其它的信息,比如frameCount,interval。对于这些我们可以另外新建一个类,用静态变量的方式储存这些信息。

每一个AS3类对应的其实是一个DoABC文件块。要注意所有导出的类必须有着独一无二的类名,因此最好用文件名+后缀的方式为类命名。另外,在DoABC文件块之后,必须跟着一个SymbolClass文件块,用来将某个AS3类和某个图片资源关联起来。

我这里讲的非常简略,具体操作起来还是有点复杂。所幸Flash的虚拟机AVM2是对外开源的,其DoABC文件格式以及字节码指令可以参见 Avm2Overview.pdf

解决资源重名
一般来说,我们导出的AS3类名是以文件名命名的,而美术做的资源文件和可能会重名。因此,我们需要确保每个导出类具有唯一的类名。一般来说,路径+文件名具有唯一性,但我们并不能以路径+文件名作为类的类名,因为这意味着文件一旦生成后路径永远不会被改变。最终,我们选择以文件名+生成时间+一个自增的值作为文件的类名。

但这样做也有一个问题要解决。我们在加载相应的swf文件后,需要使用getDefinitionByName()方法获取相应的类定义,再将对应资源new出来。如果仅以文件名作为类名,那么我们很容易就能通过文件名获取类定义。如果以文件名+生成时间+自增值作为类名,那么实际上我们在加载文件后并不知道类名是什么。

解决这个问题的办法也挺简单。在主时间轴上放置一个TextField,在TextField中保存导出类的类名。这样,在加载swf后,我们就可以通过获取场景中的TextField得到类名,再通过类名获取相应的类定义。

将SWF文件用作资源打包

时间: 2024-08-08 14:41:13

将SWF文件用作资源打包的相关文章

如何将Debug文件夹下的资源打包成一个EXE文件直接执行

如何将Debug文件夹下的资源打包成一个EXE文件直接执行 前言:前段时间写了个小程序,想分享给好友看看,可所以资源都放在Debug文件夹下,整个文件夹发给人家这也太……,为了显得稍微专业一点,想把它们打包一个EXE文件执行,因为我见到到这样的程序,直接一个EXE程序,一点直接运行,顿时感觉好吊,于是乎,搜啊搜,搞定了,总结如下. 效果图: 原来的一坨文件 现在的一个单独的EXE文件,看起来就很吊的样子 第一步:打包 将所有的文件打包成一个RAR压缩包,没错,直接打成RAR包! 第二步:解压选项

unity3d 资源打包加密

资源打包脚本,放到Assets\Editor 文件夹下 using UnityEngine; using System.Collections; using UnityEditor; using System.IO; public class assetPack : Editor { [MenuItem("Custom Editor/Save Scene2")] static void ExportResource() { // Bring up save panel string p

characterCustomezition的资源打包代码分析

using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; class CreateAssetbundles { // This method creates an assetbundle of each SkinnedMeshRenderer // found in any selected character fbx, and adds any materials that

Unity资源打包之Assetbundle

转  Unity资源打包之Assetbundle 本文原创版权归 csdn janeky 所有,转载请详细注明原创作者及出处,以示尊重! 作者:janeky 原文:http://blog.csdn.net/janeky/article/details/17652021 如果这篇文章对你有帮助,敬请关注作者<Unity手游之路>系列教程. 在手游的运营过程中,更新资源是比不可少的.资源管理第一步是资源打包.传统的打包可以将所有物件制成预设Prefab,打包成场景.今天我们来一起学习官方推荐的As

Unity3d 游戏资源打包加密(图片/XML/TXT等) C#编码 (一)

本文只是讲述一下过程,采用很简单的打包加密方法,至于需要什么样的加密结果,请大家按照需求去修改,字节偏移.前后颠倒加算法都可以,不过一般无需这么复杂,而且太复杂的加密对于极其追求运行效率的游戏来说,也是一重负担. 对于Unity,虽然Unity自身会进行压缩加密,但是其解密算法在网上随处可见,如果自己觉得游戏里面的资料具有保密性质,请对其进行自行加密. 打包加密的原理: 1.大家都知道文件都是由字节组成的. 2.一张图片之所以看起来很漂亮,是因为其数据按照一定顺序排列. 漂亮的剑灵妹子 我们可以

【Cocos2d-Js基础教学(5)资源打包工具的使用及资源的异步加载处理】

[转载]http://www.cnblogs.com/zisou/p/cocos2dx-js5.html   TexturePacker是纹理资源打包工具,支持Cocos2dx的游戏资源打包. 如果用过的同学可以直接看下面的资源的异步加载处理 首先为什么用TexturePacker? 1,节省图片资源实际大小 2,减少我们游戏中大量资源带来的内存负荷 3,方便游戏对纹理资源的内存管理 游戏开发到后期,我们或许都会遇到的瓶颈就是需要对游戏包进行"瘦身"和内存优化.那么使用TextureP

[Unity Asset]AssetBundle系列——游戏资源打包

转载:http://www.cnblogs.com/sifenkesi/p/3557231.html 将本地资源打包,然后放到资源服务器上供游戏客户端下载或更新.服务器上包含以下资源列表:(1)游戏内容资源assetbundle(2)资源维护列表,包含每个资源的名字(完整路径名)和对应的版本号[资源名,版本号],如下表所示(VersionNum.xml): <VersionNum> <File FileName="Assets.Resources.BigLevelTexture

UE4 项目资源打包,Pak包生成

UE4 项目资源打包,Pak包生成过程 项目打包过程: 1)工具代码编译 2)项目,引擎代码编译 3)资源COOK(烘培) 4)文件整理收集 5)资源打包 6)文件拷贝(exe,dll文件拷贝) Pak包生成是通过UnrealPak.exe来完成的 通过运行时传递参数 UnrealPak.exe [要生成的pak文件] -create=[要打包的文件列表] -order=[文件在pak中排序描述文件] [输出格式] [是否加密] [是否压缩] UnrealPak.exe test.pak -cr

【原创】我所理解的自动更新-资源打包流程

参数提供资源号(资源版本号),渠道号,目标目录(存放新资源包和差异包)    预处理:从VersionServer里获取相应渠道的资源,保存到目录[channel-渠道号-资源版本号]标记为NEW,遍历NEW目录里的文件并计算文件校验码(MD5之类)标记为NEWTAG_MAP,生成index文件保存文件和校验码的组合,压缩新资源+index文件并保存到目标目录.    差异包生成:从版本号1开始遍历直到新版本号-1.标记为目录OLDVER,遍历OLDVER目录里的文件并计算文件校验码标记为OLD