单个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 3187008

Scene 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 0

ActionScript Bytes Location

777 Scene 1:Frame 1
291 Scene 1:Frame 3

Bitmap 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,代码如下:

  1. package
  2. {
  3.     import flash.display.MovieClip;
  4.     import com.greensock.TweenLite;
  5.     /**
  6.      * ...
  7.      * @author ladeng6666
  8.      */
  9.     public class CodeLoading2 extends MovieClip
  10.     {
  11.         public function CodeLoading2()
  12.         {
  13.             var tween:TweenLite = new TweenLite(this,1,{alpha:0});
  14.         }
  15.     }
  16. }
复制代码

那么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,如果你有不同的想法或意见,欢迎跟我交流!

源文件下载地址

原文地址:https://www.cnblogs.com/keng333/p/3114977.html