AS中Loading 的加载

  原理:

在flash中,制作loading的目的是为了预先加载一部分内容(你可以选择全部加载完毕,或者加载一部分之后),然后再把flash的主要内容展示出来。一般来讲,loading是放在第一帧上面的(也可以不放在第一帧,比如放在任意一帧,但是在第一帧你要做个跳转,让播放头到loading的那一帧去)。这里要注意一个问题,如果你的flash程序有从元件库里导出元件的话(默认为第一帧导出),要导出的原件全部加载完毕之后才会显示第一帧的内容(即,你的loading)。这样的话很可能你在第一帧导出的内容过于庞大,占据了整个flash应用的很大一部分,比如50%,那么我们实际运行的效果就是在一段空白之后loading从50%处开始显示。

解决以上两个问题的两种方法:

第一,把要导出的元件取消导出,把它们集中放在某一帧(除开你做loading的那一帧),然后在放元件的这一帧之后的那一帧开始运行你的程序。

第二,用另个一个swf来加载需要做loading的swf。这种方法可以有比较完整的加载进度条以及百分比文字,缺点是容易引起其他问题,这个后面会讨论。

举个例子,为A.swf做一个loading,关键代码如下:

......this.loaderInfo.addEventListener(ProgressEvent.PROGRESS,loadProgress);
this.loaderInfo.addEventListener(Event.COMPLETE,loadComplete);
......AS3.0 中增加了一个新的loaderInfo类来提供已加载的swf、图像文件的信息。
flashplayer通过调度ProgressEvent对象的 loadProgress方法来实现对加载内容反馈的监听,当加载全部完成后,flashplayer再调度Event对象的loadComple方法。 loadProgress方法是自定义的监听加载进度的方法,所有有关加载的信息都可以在这个方法中加以反馈:
......privatefunctionLoadProgress(e:ProgressEvent) {
varloaded:uint=e.bytesLoaded;
vartotal:uint=e.bytesTotal;
varpercent:Number=int((loaded/total)*100);
trace(percent+"%");
}
...... 上面的代码输出正在载入内容的百分比,这是一种最简单的反馈,不过你还可以在这段代码里丰富你的loading的内容,使其更具有趣味性,使得用户在等待下载的时候能清楚的知道下载的进度,或者在这时候观赏一段精美的动画——这完全取决于自己的设计。这时候加载完成了,可以执行loadComplete这个方法了。在loadComplete方法里添加你想要的动作,比如给用户一个播放按钮以使得用户可以自主选择,或者直接进入某一帧进行播放。

      直接在swf上添加loading可能会导致loading不是从1%开始,这时候可以用一个swf加载另一个swf的方法来实现完整的 loading。

比如: 在B.swf里加载A.swf,那么在B.swf的程序里使用loader加载A.swf。需要注意的是,监听loader的加载进度需要使用loader的contentLoaderInfo属性,而不是loaderInfo。关于loaderInfo和contentLoaderInfo的关系如下图所示:

由于B.swf只起到加载A.swf的作用,并没有其他显示内容,所以它本身的加载可以忽略不计,这种方法可以比较完整的展示A.swf的加载过程。但是,同时使用这种方法也引发了一些问题,比如你在A.swf里与web端进行通信,使用了loaderInfo的parameters属性,则你在用B.swf加载A.swf后,通信将失效。这是因为FlashVars HTML 参数只影响主swf(例子里为B.swf),就是说你可以在B.swf里完成通信,但是A.swf不行。所以,我们可以先在B.swf中获取到页面要传递的信息,然后再让A.swf从B.swf中获取这个信息就可以了。通常我是这样处理的,假如B.swf的文档类为Main.as,那么在Main.as中定义一个static的属性比如prama(public static var prama),用来保存传递的信息,然后再在A.swf中通过Main.prama获取这个信息。这样就间接实现了A.swf与web端的通信。

(以上资源来源于互联网)
================================================================================================== flash自加载

关键:

import flash.events.ProgressEvent;
import flash.events.Event;
stop();

this.loaderInfo.addEventListener(ProgressEvent.PROGRESS,loading);
//添加进度监听
this.loaderInfo.addEventListener(Event.COMPLETE,loaded);
//添加进度完成监听
function loading(e:ProgressEvent) {
var loadpre:int=e.bytesLoaded/e.bytesTotal*100;
  trace(loadpre)
loadingtext.text=loadpre+"%";

}
//显示进度载入百分比-----
function loaded(e:Event ) {

loadmc.visible=false
loadingtext.visible=false
    gotoAndPlay(2)
  }

 

AS3.0的加载机制

 

:Loader


AS3.0里把所有事件,属性,加载等都集中在某个对象上了.且加载对象与各触发事件也进行了分工,这和2.0时期,onEnterFrame和不断检测加载百分比强多了!
Loader继承了基类DisplayObjectContainer,所以他可以也必须当作一个对象用addChild添加才能工作. Loader 类可用于加载 SWF 文件或图像(JPGPNG 静态GIF)文件。 使用 load() 方法来启动加载。 被加载的显示对象将作为 Loader 对象的子级添加。
: var loadimg:Loader = new Loader(); var url:String = "http://www.shch8.com/v2007/up/UploadFile/200769182617-1.gif" var urlReq:URLRequest = new URLRequest(); urlReq.url=url; loadimg.load(urlReq); addChild(loadimg);
2.0和比,还有一点区别,这里加载时要先把字符串地址转化为url加载对象,在程序中的第三行是直接设置加载对象的url属性的,也可以这样写urlReq = new URLRequest(url),除了url属性还有几个公共属性,一般很少用到如:method用来控制get还是post提交方式。
因为把加载当作一个对象了,所以就不需要象2.0时期一样,新建一个影片来装载加对的物体loadMovie(“myimg.jpg”,”mv”),我们可以直接设置他的x/y轴或宽高。还有Loader对象是二进制方式加载swf了,在flash9之前我们做加载条是用影片的getBytesLoadedgetBytesTotal来检测的是否加载完成。这不是真正意义上的加载,只是判断帧的加载数,所以会出现类似情况,加载到20%停了很久突然跳到90%因为那一帧放了整个影片70%的数据。以前在蓝色里有讨论过这个话题,还有人说是MM在走江湖!呵,现在解决了!
Loader
的所有方法:
1.
Loader() 创建一个可用于加载文件(如 SWFJPEGGIF PNG 文件)的 Loader 对象。
2.
close():void
取消当前正在对 Loader 实例执行的 load() 方法操作。
3.
load(request:URLRequest, context:LoaderContext = null):void
SWFJPEG、渐进式 JPEG、非动画 GIF PNG 文件加载到此 Loader 对象的子对象中。
4.
loadBytes(bytes:ByteArray, context:LoaderContext = null):void
ByteArray 对象中所存储的二进制数据中加载。
5.
unload():void
删除此 Loader 对象中使用 load() 方法加载的子项。


: LoaderInfo事件机制


LoaderInfo
非常好用,他是继承EventDispatcher对象用来检测网络加载状态。可以把加载动作细细地解剖出来。
原来在flash9之前,我们绞尽脑汁去获取加载来的swf的宽度、高度、帧频、版本等数据,但一直没研究出好的方法现在LoaderInfo可以做到能获取加载对象的各属性,这点很好有时用swf来加载不确定swf时很有用,可以用那些属性来重新设置主swf
加载对象所加载数据的实时检测上,PROGRESS事件可以取代以前用onEnterFrame的疯狂检测工作。当然2.0的也有自己的事件,只是很少人用!
LoaderInfo
所继承的所有事件:
1.
complete(事件参数Event. COMPLETE) 成功加载数据后调度。
2.
HttpStatus(事件参数HTTPStatusEvent.HTTP_STATUS) 在通过 HTTP 发出网络请求并且 Flash Player 可以检测到 HTTP 状态代码时调度。
3.
Init(事件参数Event.INIT) 已加载的 SWF 文件的属性和方法可访问时调度。
4.
IoError(事件参数IOErrorEvent.IO_ERROR)
在发生导致加载操作失败的输入或输出错误时调度。
5.Open(
事件参数Event.OPEN)
在加载操作开始时调度。
6.
Progress(事件参数ProgressEvent.PROGRESS)
在下载操作过程中收到数据时调度。
7.Unload(
事件参数Event.UNLOAD)
每次使用 Loader 对象的 unload() 方法删除已加载对象时,或者当同一 Loader 对象执行第二次加载并且在加载开始之前删除了原始内容时,由 对象调度。
具体测试例子请看loadjpg.swfloadswf.swf
LoaderInfo
的获取swf属性时要等swf加载完才能获取,也就是在COMPLETE事件里获取: loadswf.contentLoaderInfo.addEventListener(Event.COMPLETE, loadcom) function loadcom(the:Event):void { trace("AS版本:AS"+the.target.actionScriptVersion+".0") trace("swf版本:flash"+the.target.swfVersion+".0") trace("swf:"+the.target.width+"swf:"+the.target.height) trace("swf帧频:"+the.target.frameRate+"/") }
事件触发的各个顺序分别是OPEN>>INIT>>HTTP>> COMPLETE加载操作开始时调度>>进入事件 SWF 文件的属性和方法调度>>状态事件通过 HTTP 发出网络请求并且 Flash Player检测到 HTTP 状态代码>>加载完成

三:跨域加载的安全机制


你可以加载来自任何可访问源的内容。 如果执行调用的 SWF 文件位于网络沙箱中并且要加载的文件是本地的,则不允许加载。 如果加载的内容为用 ActionScript 3.0 编写的 SWF 文件,那么除非可以通过调用加载的内容文件中的 System.allowDomain() System.allowInsecureDomain() 方法来允许跨脚本排列,否则另一个安全沙箱中的 SWF 文件不能对它执行跨脚本操作。 如果被加载的内容为 AVM1 SWF 文件(用 ActionScript 1.0 2.0 编写),则 AVM2 SWF 文件(用 ActionScript 3.0 编写)不能对它执行跨脚本操作。 但是,可以通过使用 LocalConnection 类在两个 SWF 文件之间实现通信。 如果被加载的内容为图像,则除非该 SWF 文件的域包含在该图像原始域的跨域策略文件中,否则安全沙箱之外的 SWF 文件无法访问其数据。 在只能与本地文件系统的内容交互的沙箱中的影片剪辑不能对只能与远程内容交互的沙箱中的影片剪辑使用脚本,反之亦然。

四:主场景加载条制作


我们都知道,AS2.0是用_root. getBytesLoaded()_root. getBytesTotal()来判断swf是否被加载完,但在3.0里面_root_global_parent等原来的骨干职工都被开除了!取代他的是stage,对于场影设置,他是一手遮天了如设置swf全屏,对齐方式,显视品质等。但stage只继承了DisplayObjectContainer一部分属性,可用的还太少了。
在做场影加载条时,我们要获取场影的加载情况。要想办法把上面讲的LoadInfo事件添加到主场景去,用stage是做不到的。但可以用显视类DisplayObject 添加,他继承了 EventDispatcher,可以直接用他的属性指定主场景来添加,DisplayObject和属性和原来的movieClip还是很像的,只是前面不用加下划线作区分了如:root.loaderInfo.addEventListener()
root调度loaderInfo root.loaderInfo.addEventListener(ProgressEvent.PROGRESS, loadshow) function loadshow(the:ProgressEvent):void { var loadnum:Number=int(the.bytesLoaded/the.bytesTotal*100); showtxt.text="load:"+loadnum + "%"; gotoAndStop(loadnum); }


五:使用系统图片与加载条等组件写的加载类


package myAs

{

        import fl.containers.UILoader;//图片加载组件

        import fl.controls.Label;//文本组件

        import fl.controls.ProgressBar;//进度条

        import flash.events.Event;//输入事件类,如果代码写在帧上,可不用输入

        import flash.events.ProgressEvent;//输入事, 件类

        import flash.text.TextField;//引进文本类

        import flash.net.URLRequest;

        import fl.controls.ProgressBarMode;

        import flash.display.Sprite;

        import flash.text.TextFieldAutoSize;//调整类

        public class loadimg extends Sprite  {  

                 private var url:String = "http://image.cnool.net/picn/2005/ompic030b.jpg"

                 private var loadbox:ProgressBar = new ProgressBar();

                 private var imgbox:UILoader = new UILoader();

                 private var showtxt:Label = new Label();

                 private var titleTxt:TextField=new TextField(); //注意:上面的几个对象要声明在这里,不能放在主函数里声明,这样loadeven()等事件函数里才能认到

public function loadimg() {

                          titleTxt.htmlText="图片加载示例:";

                          addChild(titleTxt);

                          titleTxt.x=0;

                          titleTxt.y=10;

                          showtxt.autoSize = TextFieldAutoSize.LEFT;

                          showtxt.text = ""; showtxt.move(150, 10);

                          addChild(showtxt);

                          loadbox.mode = ProgressBarMode.MANUAL;

                          loadbox.move(150, 30);  

                          addChild(loadbox);

                          imgbox.load(new URLRequest(url));

                          imgbox.addEventListener(ProgressEvent.PROGRESS, loadeven);

                          imgbox.addEventListener(Event.COMPLETE, loadend);

                          imgbox.setSize(550,400);

                          imgbox.move(0, 40);

                          addChild(imgbox);

            }

        private function loadeven(event:ProgressEvent):void

        {

               //事件:加载进度显视

              var uiLdr:UILoader = event.currentTarget as UILoader;  

              var kbLoaded:String = Number(uiLdr.bytesLoaded / 1024).toFixed(1);

              var kbTotal:String = Number(uiLdr.bytesTotal / 1024).toFixed(1);

              showtxt.text = kbLoaded + "/" + kbTotal + " KB" + " (load:" + Math.round(uiLdr.percentLoaded) + "%)";

              loadbox.setProgress(event.bytesLoaded, event.bytesTotal);

          }

        private function loadend(event:Event):void

      {

          //事件:加载完成 删除事件

          //showtxt.visible = false;

         //loadbox.visible = false;//加载完成后隐藏进度条

         mgbox.removeEventListener(ProgressEvent.PROGRESS, loadeven);

         imgbox.removeEventListener(Event.COMPLETE, loadend);

        }

    }

 }

    (一些小代码)

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(); //创建文本文件

txttxt.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,0x000000,.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();

   }

}

posted @ 2012-10-12 22:04  泡沫小灰灰  阅读(511)  评论(0编辑  收藏  举报