• 老生长谈关于Loading的讨论

    日期:2009.03.22 | 分类:ActionScript3 | 标签:

    转载自:http://bbs.actionscript3.cn/thread-9078-1-1.html

    我是个新手,面对as3的Loading有点无从下手,看了很多的思路,但是都不知道哪个好,和大家讨论一下,试图得到一个完整的思路。
    现在网上关于as3的loading的文章就那么几篇,文章附于最后
    我们讨论一下什么是最好的解决办法:
    从这三篇来看
    思路大致是这样的
    1、外载其它的文件没话说,使用Loader类,loaderInfo.addEventListener(ProgressEvent.PROGRESS,你的处理函数)
    2、关于自身的loading,则分为两种观点,一种是使用一个load容器,不管什么都往其中加载,不存在main自身加载的问题。还有一种就是蓝色理想(第三篇)文章中说的可以利用SWF文档的主类的实例自身的loaderInfo属性来做。
    至于在下载字节的计算倒是没什么好说的
    function 函数(事件名称: ProgressEvent){
    var loadedPercent:int=事件名称.bytesLoaded/事件名称.bytesTotal*100;
    trace(loadedPercent)
    }
    <span id="more-268"></span>
    好我们首先讨论简单的,load容器的loading
    ***********************************
    下面这个例子借用了蓝色理想(第三篇)中的例子
    //这个例子是加载外部的文件,注意load方法只能接受URLRequest文件
    var request:URLRequest = new URLRequest("flashrek.swf");
    //定义一个loader
    var loader:Loader = new Loader();
    //为加载过程建立事件侦听器
    loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loadProgress);
    //加载完成的事件侦听器
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
    //加载过程中执行
    function loadProgress(event:ProgressEvent):void {
        var percentLoaded:Number = event.bytesLoaded/event.bytesTotal;
        percentLoaded = Math.round(percentLoaded * 100);
        trace("Loading: "+percentLoaded+"%");
    }
    //加载完成后执行
    function loadComplete(event:Event):void {
        trace("Complete");
        }
    //载入
    loader.load(request);
    //放置在场景中
    addChild(loader);
    第一篇:
    ==================
    AS3通俗教程—AS3自身loading制作
    我也来学着写教程  ,希望能对大家有所帮助,若发现问题欢迎指正!
    先说主场景舞台有内容的项目(如MV)的做法:
    有人问是不是new一个loader,然后loader.load(this),其实根本没这么麻烦,很简单,在文档类构造函数里写上:loaderInfo.addEventListener(ProgressEvent.PROGRESS,你的处理函数)就行了,处理函数这样写:
    function 你的处理函数(e : ProgressEvent){
    trace(e.bytesLoaded/e.bytesTotal);
    }
    就行了,简单吧!
    再说界面代码分离项目(主舞台内容靠AS生成)的做法:
    这个容易出错,常见错误是按照上面MV的loading一样做,这样的结果是loading一出来就是100%,
    原因在于界面代码分离项目主时间轴通常只有一帧,而flash会默认在第一帧导出类,并在此之后调用文档类的构造函数,也就是说progress事件的侦听是在加载完成后才起作用,当然看不到进度了!
    解决方法一,双文件法(代码见回复),这种方法实际是绕过去了:
    建立loader.as, 建loader.fla并设loader为文档类
    建立main.as, 建main.fla并设main为文档类
    在loader.as中
    new一个Loader实例 loader,并用load方法载入main.swf
    在 loader.contentLoaderInfo上添加progress和complete侦听
    在progress处理函数中更新textField,并在complete处理函数将loader.content添加到舞台
    在main.as中
    构建舞台内容
    解决方法二,双帧法,这才是真正解决:
    但有个小遗憾是主时间轴是2帧,但已经不错了,呵呵
    建立loader.as,再建立fla文件,保证主时轴有两帧且都为关键帧
    在fla中:
    建立一个空Mc,将此Mc拖到主场景的第二帧
    双击编辑空元件,再将此元件的时间轴改为两帧且都为关键帧,进入第二帧,将库中所有链接到类的元件拖到舞台
    将所有链接到类的元件的链接属性中的“在第一帧导出”取消掉:
    在loader.as中
    建立textField并推入舞台, 构造函数中为loaderInfo添加progress和complete侦听
    在progress处理函数中更新textField,并在complete处理函数中再添加enter_frame侦听
    在enter_frame处理函数中构建舞台内容,并移除enter_frame侦听,也就是说让enter_frame处理函数执行一次就可以了
    无效代码:
    复制内容到剪贴板代码: 

    package {
    import flash.display.MovieClip;
    import flash.events.*;
    import flash.text.*;
    //////
    public class loader extends MovieClip {
      var ttf=new TextField();///建立一个TextField实例
      public function loader() {
       addChild(ttf);/////////将TextField实例推到舞台
       loaderInfo.addEventListener(ProgressEvent.PROGRESS,progressHandler);///当进度变化时更新TextField实例的text属性
       loaderInfo.addEventListener(Event.COMPLETE,completeHandler);///////////当载入完成后显示内容
      }
      function progressHandler(e:ProgressEvent) {
       ttf.text=e.bytesLoaded*100/e.bytesTotal;
       trace(ttf.text);
      }
      function completeHandler(e:Event) {
       removeChild(ttf);//////////////载入完成后移除进度显示文本
       addChild(new main());
      }
    }
    }

    双文件代码-loader.as
    复制内容到剪贴板代码:

    package {
    import flash.display.MovieClip;
    import flash.display.Loader;
    import flash.net.URLRequest;
    import flash.text.*;
    import flash.events.*;
    ////
    public class loader extends MovieClip {
      var mainLoader=new Loader();///建立一个Loader实例用于载入main.swf
      var ttf=new TextField();///////建立一个TextField实例用于显示载入百分比
      public function loader() {
       addChild(ttf);///////////////////////////////////////将TextField实例显示到舞台
       mainLoader.load(new URLRequest("main.swf"));/////////开始载入main.swf
       mainLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,progressHandler);///当载入进度变化时更新进度显示
       mainLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler); //////////当载入完成后将main.swf加到舞台
      }
      function progressHandler(e:ProgressEvent) {
       ttf.text=(e.bytesLoaded*100/e.bytesTotal).toFixed(1);
      }
      function completeHandler(e:Event) {
       addChild(mainLoader.content);
      }
    }
    }

    双帧代码-loader.as

    package {
    import flash.display.MovieClip;
    import flash.events.*;
    import flash.text.*;
    import flash.net.*;
    //////
    public class selfloader extends MovieClip {
    var ttf=new TextField  ;//仍然建立一个TextField实例
    public function selfloader() {
    addChild(ttf);////////仍然将TextField实例推到舞台
    loaderInfo.addEventListener(ProgressEvent.PROGRESS,progressHandler);//仍然当进度变化时更新TextField实例的text属性
    loaderInfo.addEventListener(Event.COMPLETE,completeHandler);//////////仍然当载入完成后显示内容
    }
    function progressHandler(e:ProgressEvent) {
    ttf.text=e.bytesLoaded * 100 / e.bytesTotal.toFixed();
    trace(ttf.text);
    }
    function completeHandler(e:Event) {
    this.addEventListener(Event.ENTER_FRAME,enterframeHandler);//添加enter_frame侦听
    trace("载入完成");
    }
    function enterframeHandler(e:Event) {
    if (currentFrame == 1) {///////////////////////////////////////等于1或是2都可以,1更好
    stop();//////////////////////////////////////////////////其实这个stop()可以不加,加上更好
    removeChild(ttf);//////////////////////////////////////////////////仍然移除进度显示文本
    this.removeEventListener(Event.ENTER_FRAME,enterframeHandler);/////必须移除侦听
    addChild(new main  );
    trace("OK");
    }
    }
    }
    }
    ======================
    第二篇:
    ======================
    AS3.0新手必读-影片Loading
    原代码说明:
    1帧: 

    /*********************************
    AS3.0 LOADING CODE
    <a href="http://www.mhhf.net">www.mhhf.net</a>
    MAGIC WING STUDIO
    BY 2007-09-01
    **********************************/
    stop();
    stage.scaleMode=StageScaleMode.NO_SCALE;
    //设置舞台属性不跟随播放器大小而改变
    stage.showDefaultContextMenu=false;
    //屏蔽右键菜单
    stage.frameRate=30;
    //设置帧频为30
    var stageW=stage.stageWidth;
    var stageH=stage.stageHeight;
    //取得舞台宽和高
    var loadclip:MovieClip=new MovieClip();
    //创建LOADING MC loadclip
    this.addChild(loadclip)
    //添加loadclip到舞台
    var txt=new TextField();
    //创建文本文件 txt
    txt.autoSize=TextFieldAutoSize.CENTER;
    //文本文件自适应大小并且居中显示
    txt.text="AS3.0 Loading...";
    txt.textColor=0x000000;
    //设置文本颜色
    txt.selectable=false;
    //文本设置为不可选
    txt.x=stageW/2-txt.width/2;
    txt.y=stageH/2-txt.height/2;
    //设置本文件放置于舞台中央
    loadclip.addChild(txt);
    //将文本实例txt添加到loadclip
    var stgb=new Sprite();
    stgb.graphics.lineStyle(1,0x000000,1);
    stgb.graphics.beginFill(0xff0000,.5); //采用单色填充,红色透明50%(.5) stgb.graphics.drawRect(0,0,200,10); stgb.graphics.endFill(); stgb.x=stageW/2-stgb.width/2; stgb.y=txt.y+txt.height+5; loadclip.addChild(stgb) //绘制进度条底色并且添加到loadclip
    var stg=new Sprite();
    stg.graphics.lineStyle(1,0×000000,.5);
    stg.graphics.beginGradientFill(GradientType.LINEAR,[0xff0000,0xffff00],[100,100],[0,255]); //采用渐变填充 红–黄 stg.graphics.drawRect(0,0,200,10); stg.graphics.endFill(); stg.x=stageW/2-stg.width/2; stg.y=txt.y+txt.height+5; loadclip.addChild(stg) //绘制进度条并且添加到loadclip
    this.loaderInfo.addEventListener(ProgressEvent.PROGRESS,loading); //添加进度监听 this.loaderInfo.addEventListener(Event.COMPLETE,loaded); //添加进度完成监听
    function loading(eve) {
    var loadpre:int=eve.bytesLoaded/eve.bytesTotal*100;
    txt.text=”影片载入”+loadpre+” %”;
    stg.scaleX=loadpre/100; }
    //显示进度载入百分比—–
    function loaded(eve) {
    txt.text=”影片载入完毕!”;
    }
    if (framesLoaded == totalFrames) {
    removeChild(this.getChildAt(0));
    nextFrame();
    }
    }

    =====================
    第三篇:
    =====================
    http://bbs.blueidea.com/thread-2744638-1-1.html
    这篇我没有摘原文,因为有图片和附件需要在原来的帖子上看
    =====================