单个SWF文件loading加载详解
首先感谢activetuts的帮助。
对于一个完整的游戏来说,loading是比不可少的,如果游戏要加载10秒中,我相信没有人愿意在这10秒钟都看着空白的舞台。
但是我在单独的SWF文件中添加loading总是会遇到一些莫名其妙的问题,它总是到加载了80%之后才开始动。试过了各种办法都是失败,如果你也和我有相同的困扰,那就来分享我的经验吧。
你可能会说了,我可以用一个体积小的SWF去加载另外一个体积庞大swf啊,是的,没错,不过有时候,我们的游戏别无选择的只能做出一个swf文件,比如老板苦逼时,比如上传到一些flash游戏网站时等等。
注意:本教程适用于Flash CS4以上版本。
加载的内容
谈到加载了,肯定要先弄清楚,我们都加载了什么东西。Flash中加载的内容不外乎代码和素材
代码
代码是游戏中比不可少的,所以它的体积也是不可忽视的。特别是规模较大的游戏,可能会包含很多第三方的类库,如Box2D、Tweenlite等等,都会影响loading的进度。根据代码的位置不同,主要有三类:
- 时间轴上的代码
AS2时代的代码基本上都是写在时间轴上的。
- 文档类
在文档属性面板中,设置的文档类,相当于把代码写在主时间轴上的第一帧。如下图所示
- 绑定类
在元件属性面板中,设置的绑定类,我们可以用AS3和绑定类名称来实例化这个元件,而不用将该元件拖至舞台上。
素材
素材占据了SWF文件的绝大部分,主要包括元件(MovieClip、shape、Button)、位图、声音、字体。但是他们对加载的影响是相同的。
带宽查看器和体积报告
在学习加载顺序之前,我们先看看flash的这两个功能。
带宽查看器
编译完SWF后,在播放器中选择视图->带宽设置(Bandwidth Profiler),可以查看SWF每帧所占带宽的比例,如下图:
如果第一帧的高度比后面的高,就会出现开始我说的,加载80%之后,进度条才开始动。
体积报告
通过带宽查看器,可以看到SWF中每帧所占带宽状况。另外,我们还可以在Flash发布设置中,选择生成体积报告,图下图中第4项
勾选这一项之后,发布flash时,会自动在fla目录中生成一个名为”文件名 Report.txt”的文本文档。里面详细了记录了flash加载的数据,如下所示:
Frame # Frame Bytes Total Bytes Scene
1 2145 2145 Scene 1
2 1 2146
3 3184861 3187007 (AS 3.0 Classes Export Frame)
4 1 3187008Scene Shape Bytes Text Bytes ActionScript Bytes
Scene 1 0 0 1068
Symbol Shape Bytes Text Bytes ActionScript Bytes
ExportAndLink 0 0 0
ExportNoLink 0 0 0
Image 0 0 0
noTweenLite 0 0 0
Sounds 0 0 0
withTweenLite 0 0 0ActionScript Bytes Location
777 Scene 1:Frame 1
291 Scene 1:Frame 3Bitmap Compressed Original Compression
有了上面这两个工具,我们可以更清晰的了解和设置每个内容的加载顺序
加载顺序
不同的内容,加载顺序也是不同的。相同的代码,不同的位置,加载顺序也不尽相同。更加让人迷惑的是那个”类导出帧”,用法让人扑朔迷离。和上一节一样,我们根据加载内容来讨论加载顺序。
代码加载顺序
为了形成更直观的对比,在进行详细的测试之前,我创建了一个名为CodeLoading.fla的空白文件,里面除了3个空白帧,和一句stop()什么都没有。在自动生成的CodeLoading Report.txt中,每帧的大小如下:
Frame # Frame Bytes Total Bytes Scene
1 862 862 Scene 1 (AS 3.0 Classes Export Frame)
2 0 862
3 0 862
接下来,我用不同的方式在这个CodeLoading.fla中加载TweenLite这个大家常用的类,来看看各种代码方式的对加载的影响:
- 时间轴代码
主时间轴上用到的任何代码都会再第一帧加载,与”类导出帧”位置无关(稍后我们再详细讨论”类导出帧”)。这里说的用到,不包括import语句,而是指new等语句,flash对import而没有用到的代码视而不见。
例如,下面我们在CodeLoading-1.fla主时间轴的第3帧,创建一个TweenLite对象,在自动生成的CodeLoading-1 Report.txt中,每帧的大小如下:
Frame # Frame Bytes Total Bytes Scene
1 5851 5851 Scene 1 (AS 3.0 Classes Export Frame)
2 1 5852
3 1 5853
- 文档类
文档类和它用到的所有的代码和类,以及文档类调用的类里的代码等等。始终都在第一帧加载。
例如,我为CodeLoading-2.fla设置了文档类CodeLoading2.as,代码如下:
package { import flash.display.MovieClip; import com.greensock.TweenLite; /** * ... * @author ladeng6666 */ public class CodeLoading2 extends MovieClip { public function CodeLoading2() { var tween:TweenLite = new TweenLite(this,1,{alpha:0}); } } }
那么CodeLoading2.as和TweenLite.as都将在第一帧加载。另外如果TweenLite.as还用到了其他的类,那么这些类也会在第一帧加载。在自动生成的CodeLoading-2 Report.txt中,每帧的大小如下:
Frame # Frame Bytes Total Bytes Scene
1 5805 5805 Scene 1 (AS 3.0 Classes Export Frame)
2 1 5806
3 1 5807
- 绑定类
影响绑定类的主要因素是绑定该类的元件与”类导出帧”的位置关系。
前面我们多次提到了”类导出帧”,这到底是个什么东西呢?它表示在编译SWF文件时,所有相关的类文件导出到帧位置, 默认位置是第1帧。在Actionscript3.0设置面板中可以修改”类导出帧”的位置,如下图,我将其改为第3帧:
- 当绑定类的元件在”类导出帧”前面时,绑定类在第1帧加载。示例请参考CodeLoading-3-1.fla。下面是CodeLoading-3-1.fla编译后生成的CodeLoading-3-1 Report.txt内容:
Frame # Frame Bytes Total Bytes Scene
1 5928 5928 Scene 1
2 26 5954
3 3 5957 (AS 3.0 Classes Export Frame)
4 1 5958
- n 当绑定类的元件在”类导出帧”之后时,绑定类在”类导出帧”(即第3帧)加载。示例请参考CodeLoading-3-2.fla。下面是CodeLoading-3-2.fla编译后生成的CodeLoading-3-2 Report.txt内容:
Frame # Frame Bytes Total Bytes Scene
1 1038 1038 Scene 1
2 1 1039
3 4962 6001 (AS 3.0 Classes Export Frame)
4 9 6010
绑定类的加载顺序与该元件是否在”类导出帧”导出(即是否勾选下图的第2个选项)无关。
元素加载顺序
说完了代码的加载,接下来,我们来说说元素的加载。前面我讲过元素有很多种,主要包括元件(MovieClip、shape、Button)、位图、声音、字体。但是他们对加载的影响是相同的。不外乎元素所在帧和”类导出帧”:
- 元素在其所在帧加载
所有舞台上的元素都在其当前帧位置加载,通俗的讲,就是这个元素放在第几帧就在第几帧加载。
如在AssetLoading-1.fla的第4帧放了一个MC,编译后的AssetLoading-1 report.txt中加载数据如下(类导出帧设置为第3帧):
Frame # Frame Bytes Total Bytes Scene
1 1185 1185 Scene 1
2 1 1186
3 1 1187 (AS 3.0 Classes Export Frame)
4 25084 26271
可以看出,MC在第4帧加载。
- 元素在”类导出帧”加载
前面讲的元素都是在当前帧位置加载的。但当元素放在”类导出帧”之后,而且元件的属性面板中勾选了在”类导出帧”导出的话,元素将在”类导出帧”位置加载。注意,库中任何未用到的元素,默认也是在”类导出帧”加载。
在AssetLoading-2.fla的第4帧放置了一个同样MC,另外我在MC的属性面板中设置”导出至第3帧”,加载数据如下:
Frame # Frame Bytes Total Bytes Scene
1 1187 1187 Scene 1
2 1 1188
3 25322 26510 (AS 3.0 Classes Export Frame)
4 10 26520
看以看到MC加载数据跑到第3帧去了。
明白了代码和元素的加载顺序后,我又遇到了另外一个问题。我的代码基本都在Main类里,用它作为文档类,会导致所有的代码都在第一帧加载,放在时间轴上也是在第一帧加载,如何是好?另外,怎么样将所有的元素统一到一帧加载,而又不会显示出来呢?
为了解决上面两个疑问,我创建了两个MovieClip,分别为CodeHolder和AssetHolder,顾名思义,就是分别用来加载代码和元素。其中CodeHolder绑定Main类,拖动一个CodeHolder到舞台的第3帧,当时间轴播放到第3帧会自动调用Main的构造函数。具体详见源文件中的Main.fla。
好了,全文结束,希望我的经验分享能解决你遇到的困难,让你少走些弯路。记住我是ladeng6666,如果你有不同的想法或意见,欢迎跟我交流!
源文件下载地址
联系作者
Main.fla中如果删除库中的AssetHolder元件,数据加载都在第二帧。。。?
是这样的,你可以删除一下试试!
好东东,以后做东西就能优化加载了嘿嘿
恩加油!!
很好
谢谢你的关注
想问下那个带宽监视器是咋弄的?是不是只有在早期版本才有啊
文章里有讲啊,在视图菜单下面可以调出来。
拉登用的flash cs是哪个版本,我的flash cs5.5, Export in frame 1,这个1不能修改,奇怪。
加我qq聊吧,q:328800655