旋转渐进式Loading制作(AS2.0 OOP)

2006-11-18 21:34 | Army


我至今还记得我的第一作Flash中那个Loading进度条的制作——它简直像一个笑话。也就是在去年吧,当时初次接触Flash(那时是MX2004版本),正好因为同时负责着专题,于是心血来潮的我就想一鼓作气把专题Flash化,后来证明这个举动不仅是疯狂的,更加是冒失的。

开始我并不懂AS,甚至根本不知道它。在做第一个Loading进度条的时候,我只是简单地作了一个矩形伸缩的补间动画,没有任何的判断依据。后来mummy出现告诉我AS的知识和相关用法,也就是从那时开始,我的AS编写走上了前进的道路。

然而有谁又能想到,当初不知道什么是AS的我,今天竟然在编写一个复杂的Loading进度条呢?呵呵,我的习惯就是每篇教程之前喜欢先来段“有意义的罗嗦”,但愿不要因此而使读者感到厌烦。

依旧,这个的源文件地址是:

http://ff9.ffsky.cn/flash_teach\load/exp.rar

我就不用图片叙述元件组成了,因为里面确实没什么,你一打开都能看明白:
pic.jpg是我随便找的一张图片,用它只是因为个人喜好而已(我是红眼loli控~XD)它的唯一作用就是增大文件体积,让我们感受到下载过程中Loading进度条的变化。
元件1和元件2是我制作的一个小4边形,即进度条,你完全可以把它画得更漂亮些。元件2的链接名为“bar”,在右键-链接里能看到。
舞台中央放置了一个名为pct的动态文本。
第5帧放了那张红眼loli图片。

我们来看下as文件:

class LoadBar {
  var num:Number = 1, d:Number = Math.PI * 2 / 9, i:Number, size:Number, loaded:Number;
  var clearLoading;

  function initialize():Void {
    for(i = 1; i < 10; i++) {
      _root.attachMovie("bar", "bar" + i, i);
      eval("bar" + i)._x = 275 + (100 - 3 * i) * Math.cos(d * i);
      eval("bar" + i)._y = 200 + (100 - 3 * i) * Math.sin(d * i);
      eval("bar" + i)._rotation = 40 * (i + 2.3);
      eval("bar" + i)._xscale = eval("bar" + i)._yscale *= 1 - 0.05 * i;
      eval("bar" + i)._alpha = 100 - 10 * (i - 1);
    }
    i = 1;
  }
  function startLoad():Void {
    loaded = _root.getBytesLoaded();
    _root.pct = Math.floor(loaded / size * 100) + "%";
    if(loaded >= size) {
      clearInterval(clearLoading);
      trace("Finish!");
      _root.play();
      for(i = 9; i > 0; i--) {
        eval("bar" + i).removeMovieClip();
      }
    }
    if((loaded >= (size / 55 * num))) {
      num++;
      eval("bar" + i)._alpha -= 10;
      if(eval("bar" + i)._alpha <= 0) i++;
      trace(eval("bar" + i)._alpha);
    }
    trace(loaded + "/" + size + " = " + _root.pct + "\n");
  }
  function loading():Void {
    clearLoading = setInterval(this, "startLoad", 10);
  }

  function LoadBar(size:Number) {
    this.size = size;
    trace("The file size is : " + size + " byte.");
  }
}


变量中唯一要介绍的就是d:Number = Math.PI * 2 / 9这个,其实在我的第一篇教程中已经出现了类似的东西。Math.PI是AS内置的数学常量π,乘以2就是圆周360度,除以9是因为我放了旋转的9个进度条。

构造器LoadBar接受数值型的size为形参,并将它赋值给类本身的size变量。从名字上我们就可以猜出,size是指swf文件的大小。

initialize()初始化函数是将9个进度条按照一定规则排列在舞台上。这里,我们用了attachMovie、三角函数和圆的数学模型,你是否觉得眼熟?没错,它很像第一篇教程中那5个按钮,只是稍微有点区别而已。
attachMovie将9个bar放置在舞台上。
后面两句是设置它们的坐标值,Math是AS的内置数学类。在这里,我设置这9个MC不断像圆心(275, 200)靠拢,你可以把(100 - 3 * i)这句去掉试试看。
接着我设置每个MC的旋转角度,以使它们全是朝向圆心的。这里面的数学计算有些烦人,有兴趣的就去研究一下吧,我就不做解释了。
然后我设置每个MC的缩放值,这样9个进度条看起来就是依次变小的了。
最后再依次设置它们的透明度,如此看上去大的MC近些且透明度更高,小的远些且透明度更低。它们在一起像不像一个旋转楼梯?

startLoad()是一个判断加载半分比的方法。
loaded赋值为_root目前加载了多少字节,然后除以总字节数乘以100,再取整加上“%”号变成字符串赋给_root.pct,这样那个动态文本就能显示已读取百分之多少了。
接下来的if句是判断是否读取完成,然后停止clearLoading执行函数(后面会出现,它其实就是执行startLoad()方法的),让_root播放并用removeMovieClip()删除那9个加载的进度条。
再下面的if句可能有些难以理解,我来详细说明下。
舞台上的9个MC有着不同的透明度,依次是:100、90、80、……、20、10。我设置每读取了一定字节的文件后最大的那个进度条透明度自减10,当减到0之后消失,由次大的进度条循环开始。如此反复。这样计算的话,9个MC一共能自减55次透明度(10 + 9 + 8 + …… + 2 + 1 = 55),这也就是判断条件(loaded >= (size / 55 * num))的意思。num初始值为1,每次大于55 * num之后num自增,再继续判断。
最后的loading()方法已经很清楚了,它只有一条语句,将执行startLoad的函数赋给clearLoading,以便加载完成后清除。

好了,as介绍完了,在fla文件中的代码更加一目了然。时间轴第1帧:

stop();
var size:Number = _root.getBytesTotal();
var b1:LoadBar = new LoadBar(size);
b1.initialize();
b1.loading();


首先我们要它停止在第1帧,在把swf文件的大小赋给size变量,再传给b1对象的构造器。然后调用b1的initialize()方法,最后loading()。

在第5帧放置那张红眼loli的地方,只加了一句stop()语句用以停止住。


好了,整个都介绍完了。Ctrl+Enter测试影片看看吧,记住要用测试才行!因为这个本来就是个下载进度条,你直接在本地观看的话是没有任何效果的。测试选项里速度调得越低的话越利于观测,我用DSL(32.6 K/S)已经足够了。

最后,知道这个教程从思考到制作再结束用了我多少时间吗?1个小时零14分钟,我很高兴能看到这样的结果。
所以,这次我给读者们出的问题就是——你是否能在1个小时零14分钟读完并读懂这篇教程?一些达人们可能要笑了:这东西1分钟零14秒就够了!