查看完整版本: 原创-完美的loading-吐血整理!

鸡冠花 2008-5-15 15:07

原创-完美的loading-吐血整理!

共三部分:
9c+f/n$OB s] i 1、基础9{(S#_"gr"xl~
2、MovieClipLoader相关讨论(较深入) p1C:J ? i z{
3、V2组件相关问题T)Q%A'C:F"W[

2]O9Iy k[$piJJ 一、基础MS)uz `+G
很久没有发技术日志了,要来就来个完美的。您别激动,一个小小的loading谈什么完美,我想你看了就知道^_^
sj { Vu1WA 我的口号,将此文打造成全球最完善的非Flash初学者loading教程贴。
(s:R/wk.s"x.@Xi 转载请保留原文地址:[url]http://www.awflasher.com/blog/?id=444[/url]#d&X]4J.M1[*t0S

&i| ir(G9]3Y 首先,想说一下我写此文的动机。记得很早之前我曾经说过“没有loading的flash,不是完整的flash”。我想那个句话可能偏激了。因为有时候一些不到10k的flash,确实不需要做什么loading。但我始终认为,做一个优秀的loading是衡量一个flasher水准,甚至态度的。你问我为什么,我可以告诉你,因为loading是唯一一个你不会多看而所有用户、客户会看的东西,所以你对loading的重视程度,甚至可以反衬你这个flasher的职业道德!KmLk8`(F8H

6B(n:V"~%w@-P;r+xM 有些做设计为主的朋友,我认识不少,他们对loading都是得过且过的态度,做一个loading,更多的是自己找一个现成的,然后每次去套用,我个人认为是很不好的习惯。并不是说我不提倡代码、元件的重用度,而是我觉得对于loading这种东西,套多了,是要出问题的。我强烈建议那些已经达到可以修改人家loading水平的flasher看看我的东西,当然,如果你连flash的as该写在哪都不知道,建议先入门了。
,g/cEG5Z/k)fn
1p/z8Yq'?M 好,下面切入正题,如何制作loading。*dA#u b+R2h
JB?1r*IY7u%t
首先要感激Macromedia的大智慧,提供了很好的两个函数使我们可以做出完美的loading,那就是getBytesLoaded和getBytesTotal。请不要再用你改来改去改了两三年的那个什么getFrameLoaded什么什么了,我都记不清楚怎么拼了。我只想说,Frame的观念将在真正的Interactive -Design中淡化。更别提什么Scene,那是Flash的败笔!6lIe6E.g
{a9i#h,Q6T$h$Y
那么loading如何工作呢?我们如何利用这两个函数呢?这里要提到一个重要的概念。就是间隔调用。间隔调用有多种方式,下面列举出来,并列举出其在loading制作中的地位和用法,欢迎补充:%A^l^'qT
1Uz"Q0p$k8Ec'Ds
·setInterval方式
A D"j p L$kLL 写法:%[MNx1^2oB\'b
function loadCheck()
;W6m:N1}3@^i1r {
o;IfEk6\,D&M)gX)]   var p = getBytesLoaded()/getBytesTotal();;uJpU8Go
  if (p==1)
:q;lmt8^B.`V   {
j+gu6O#_Oj#c1@3W     clearInterval(intervalID); // 释放间隔调用
T7vNq3i F]     gotoAndPlay(someFrame); // 开始播放l~ ^r2N
  }
9h"v8ys%{R_&H }6Kw:]!HrC]an
var interval = 30; // 这个数值是刷新频率k6\ @ `Pp/aQt
var intervalID = setInterval(loadCheck,interval);A1R X.yk S~'Md
0\Q8b)}Jw;AQ,t
我个人并不推荐初学者用这种写法。因为很多人容易忽视clearInterval,而这个东西被忽视掉,是很恐怖的!如果你的setInterval没有给及时移除,意味着你将在整个swf的播放过程中增加一个没有必要的负担!
BPgI wQ3n*[ 而且这种方法很不适合控制MoiveClip的状况(因为初学者会发现MC的路径是个大问题,而loadCheck本身就是个函数,还是被 setInterval调用的,要在loadCheck中指一个路径出来,挺麻烦的,你不要指望_root,那样会让你的程序不规范;也不要指望 this,因为在函数中用this似乎不太理想;最好什么都不写,但往往你不敢不写),进而做出更好的效果。
s5F$c ~Bc*E%k|
T(uIiVg ·onEnterFrame方式bUYPS'KcwG
我最喜欢的就是这种方法了。比较方便、直观。
2F%IMv|L.K 因为往往我们是要用一个MC体现一个loading的进度,比如,一个进度条,或者更有创意的东西,只有你不能想到的,没有你不能做到的。BvJk Z%ys
那么究竟如何用呢。首先,把创意定好。然后给你的MC一个实例名字,比如叫做loader_mc。这时候在timeline上写代码,记住,是 timeline而不是MC上。因为这样便于代码统一、便于路径统一、便于管理和寻找。别为了省几个字母就把代码通通搬到button,mc上面去,然后一个on(press)了事。除非你是在敷衍你的作品;或者你是在为了交作业。
(sK#Yd\\ loader_mc.onEnterFrame = function ()
3ru I!C%G$dfT5}%| { wWzD1a!_d)k5r
  var getTar:MovieClip = this._parent;
HKv3MP2M   var p = getTar.getBytesLoaded()/getTar.getBytesTotal();{"[2r$F Q1DElj
  trace(p);
)Cx N^ Zx"D,_|h   if(p==1)
y_P&I&KH&S*~   {
L!d._R9t3tm3j;B     this.onEnterFrame = null;
2?v0R'_+i:uk     gotoAndPlay(someFrame); // 开始播放3x7k|4U\ {z'A~I t
  }WG,}[ ps!s
0g.Lj7q ] nWgw
}XAD*N*[?.K,I

6d)eX%nTd:c,k$g 就这么简单,记住,在MC的事件函数体内部引用MC,永远是一件很快的事情。因为this就可以指向这个MC本身,通过诸如this._parent之类的方法,可以找到你所有的MC!L X |3it2f

;N5N;Zt%j ·直接依赖于timeline的循环方式#fJ[6|LXo
非常非常非常古老的方式了,不介绍了。不过你们可以去问问那些一直不喜欢自己动手做loading的flasher,他们也许在改的某一个版本就是这个,呵呵。
yd&A,fl z*j$e(Rb l6W$SfZ W
以上算是比较简单的。比较容易出问题的,还有两个。"AwPII.m
第一、MovieClipLoader!@6R*v5j8[6C
第二、含有多种V2组件的Loader
/W+e5[Pz3m t-b@(C fM hoCw$d
================================W%{~7qRt*J7U

5l gfrb 二、MovieClipLoader类说明&r/qe{ f;`x$P,t
h+]1ZOhj

c/zA#MC9g8@hX0@&S 参考英文教程,并作出大量原创补充 - Neil Webb, neil AT nwebb DOT co DOT uk, [url]http://www.nwebb.co.uk[/url] rg5YTsG'T x
转载请注明原帖:[url]http://www.awflasher.com/blog/?id=468[/url]
)wUXgDk q ?Fn] H)GJ,A7g!?
读取外埠数据参与Flash应用程序部署是一件非常重要和常见的工作,尤其是我们常常需要检测这些数据加载的进度。而MovieClipLoader(下称 MCL)类却帮我们大大简化了这项麻烦工作。此外,它使得我们能获取更多的需要,并减少代码量。我们可以用一个单独的MovieClip类来载入一个,或者多个外埠资源到指定的MC或者层级,或者我们可以为每一个加载工作制定不同的MCL实例。
s2Dw|'t3n
/n+E1l*H&L 我决定分两部分来完成这篇教程。首先,我们将介绍MCL的基本用法;然后我们将介绍如何使用一个单独的MCL实例来读取外埠资源到不同的MC,并且,我们将加入侦听器对象来参与工作。当然,不通过侦听器也可以完成任务,我们暂时不介绍侦听器,因为这样你会更加容易理解MCL。 J)fJ3ejM
%v~2b!cBv_
那么,我们首先来大体了解一下MCL有哪些回调函数,后面也会有详细介绍(aw附:回调函数我个人理解就是某一个类组、参数事先确定,拥有指定功效的方法)这里可以了解一下什么叫做回调函数):a"X"?[1Ov;RBy2_z

0br'vA#K MovieClipLoader对象的回调函数:#g,oa,pI%Os

f$j(Vb5Q h5H 事件回调函数(严格要求数据类型的时候,它们并不是方法,后祥):$d p%Z"O E:TTN(P
* MovieClipLoader.onLoadStart() - 当加载开始的时候触发
,^_2|#Q d * MovieClipLoader.onLoadProgress() - 在读取进行中触发;T/H(w Z ~p
* MovieClipLoader.onLoadInit() - 读取资源载入后的第一帧执行完成后触发
uR3K4m(tJ)_)VZJ * MovieClipLoader.onLoadComplete() - 当读取的外埠资源已经完全下载到本地时触发。
'H4f3S/T[ ]Oc * MovieClipLoader.onLoadError() - 当加载外埠资源出错时触发。
&VT1X6h-e/[/M.Y * MovieClipLoader.unloadClip() - 将加载的外埠资源移除或终止一个加载工作。'P8o5T2fI8[^

V oM d3Ri 方法回调函数:
}5y)O]T H1Y"P * MovieClipLoader.getProgress(target:object):object - 读取外埠资源的进展,参数为MC对象(aw附:其实MC这种数据类型也就是一种对象)。返回一个对象,该对象包含两种事先预定好的属性(后祥)D d7E_5C;n_ MLH

~oYlG\D 要想好好理解这些回调函数,我们动手试验一下是最好的方法。当然MCL是Flash7之后才有的,所以别忘了发布的时候发布成为7+的版本号。如果直接用 FlashPlayer来调试可能会遇到一些问题,我们推荐在浏览器中进行调试(个人意见:对于外埠资源难以获得情况,比如教育网获取公网资源,最好不要在IDE中调试)
[?&rN2QW
;GRJU?5HqY 在我们的例子中,我们将用一个MCL对象来读取不同的图片,并将它们置入不同的空MC中。本例中要用到的swf文件和图像源文件将在Actionscript.org找到(个人建议:其实看完这篇文章要不要源文件没有必要了)
4vBN%x,E Ta!C
7LW%c*PqD2u6]z ==========
o\5_` n5i
#T:tNp-M'A1[VE 1、建立一个新的Flash文档,并在第1帧输入以下脚本:
D yy)SF!g W _root.traceBox.vScrollPolicy ="on";
7}3D1h%S3m W9Jk function myTrace(msg)
H#~"v7Q[ {
`$Y2\3u'Qm _root.traceBox.text += msg + newline;
0O8| D3aCb _root.traceBox.vPosition = _root.traceBox.maxVPosition;
2e3Y/h&g,Rk/T }\3lRz"t/X'U4k/E
我们这里是在建立一种跟踪调试机制,调试的(变量)将输出到文本框组件中。这里的方法"myTrace"是预先定义好的一个函数,它帮助我们顺利完成对某些信息的监控;其中第二句的作用是使文本框随时输出最新监控值。6l ?Yj7d0r8gQ |[

7q]/^0c8@&n 2、现在从组建库托拽一个TextArea组件进入场景,并给以合适的大小,以及一个实例名称traceBox(对应上面的脚本)k#Z/YWl(Zp9S

6~xnf+SxAsh'c 3、接下来,我们要建立一个新的MC元件。并在场景上部署3个实例,为它们分别命名为myMC1,myMC2,myMC3。我们将把图片或者swf影片装载进入它们,并且,在它们下载到本地后按照需求调整它们的尺寸。其实,对图片人为地改变尺寸会造成许多不好的后果,比如锯齿的产生,但是为了让大家了解 onLoadInit事件的使用,我们将会这么做。-l A4mYL8K S5T L

4C/HC)Mj_o#A!? 4、然后,我们建立一个MCL对象,在第一帧输入以下脚本:
5}_iE;B var myMCL = new MovieClipLoader();//create an instance of MovieClipLoader*I&H.H*T1FXL
aw附:这里我想罗索以下,关于Object的翻译。因为上述代码的注释中,老外用的是instance这个词,直译的话,Object是“对象”;Instance代表“实例”。前者更注重于其数据类型,而后者则更注重于其客观存在性。
8Y,G)kq9O/sQ
^1J1DJ3a y,ZZ [ 5. 现在我们就可以部署脚本了,在第一帧:/UKG?\@}
myMCL.onLoadStart = function (targetMC)J y%x;QD
{
6WK7G M\ var loadProgress = myMCL.getProgress(targetMC);
7nv/^UfR o.ios,u!h myTrace ("The movieclip " + targetMC + " has started loading");fnagM8F^
myTrace("Bytes loaded at start=" + loadProgress.bytesLoaded);
XAT f$bq myTrace("Total bytes loaded at start=" + loadProgress.bytesTotal);
/ib$z)v Z_;d:T)N }L`9`.C(n-n#[a4O
这个函数的第一行中申明了一个(对象类型的)变量,显然,这个变量的值由myMCL对象的getProgress方法获得.刚才已经介绍了 getProgress方法,这里可以看到,返回的loadProgress.bytesLoaded就是loadProgress对象的 bytesLoaded属性.
}F'S"` m wR 这里我在啰嗦一句:为什么返回一个对象,而不返回具体的值。这是有原因的。函数返回值的功能使得程序设计更加完美,然而很多情况下,我们要返回的并非一个值,我们可能返回两个或者更多的值,甚至它们的数据类型都不相同。这样,只有通过对象的形式来返回了。这是解决问题最简单最高效的方法。下面三句myTrace就呼应了之前我们定义的监控函数,这样就能看到我们关注的变量了。4b'Q7Uu c X*FK:pu
;i'tzJ&~C~ |
6、我们已经为 onLoadStart事件部署了相应的工作,接下来我们要为上述其他事件部署工作了。紧接着是onLoadProgress,它接受三个参数: targetMC, loadedBytes, totalBytes。分别代表目标容器MC实例;已经读取的体积、总体积。
4t+G%^+p xJNp g myMCL.onLoadProgress = function (targetMC, loadedBytes, totalBytes) {
J1o,k?n.N~,` myTrace ("movie clip: " + targetMC);L/[%e#\6Hm,@*t'j
myTrace("Bytes loaded at progress callback=" + loadedBytes);@P0@ZI"u-A/lc/v
myTrace("Bytes total at progress callback=" + totalBytes);)g0[YU&\+a%D:z+J1E
}P5V6QfB\ H!J/N
IL5qI ~W1r
7、我们的onLoadComplete方法仅接受一个参数,它就是容器MC实例。像onLoadStart一样,我们用getProgress方法来返回读取情况。"o nu I[8i1v*Z+A|bf
myMCL.onLoadComplete = function (targetMC)
/d8LW g%L-t1?%Z]Z {
i_#my6G var loadProgress = myMCL.getProgress(targetMC);WY/W#HU/@c
myTrace (targetMC + " has finished loading.");
/j5mQ'xH+X myTrace("Bytes loaded at end=" + loadProgress.bytesLoaded);
!F| r o)@&H myTrace("Bytes total at end=" + loadProgress.bytesTotal);
"|&}B5e8H)a$cV}l }
K9{UB;b8uX;a*U
J^XBN E 8、onLoadInit方法将在所有加载的内容被下载到本地容器MC中之后才开始执行。这将使得你能更好的控制加载进来的内容的属性。我选择的图片非常大,这样我们可以把读取过程看得更加清晰,而我也要对已经加载的图片尺寸进行修整,让它能全部显示出来。0gD b`XI~
myMCL.onLoadInit = function (targetMC)
M}8tUX2r@ { c4_ g%Xh*\ w!bO
myTrace ("Movie clip:" + targetMC + " is now initialized");
c X%dt ^@ targetMC._width = 170;
3Tf(taOk1j1V|!Nb'@%uz targetMC._height = 170;(Oueu2T!?Qj7q8B
}
9s6y c }6Z u,A/`3`MX
7l.J$e"PJ"q/O 9、还有一个回调方法onLoadError。如果有错误发生,它将会被触发。作为一个优秀的程序员,部署完善的应用程序的时候,对错误发生的避免措施是必不可少的!Pz"s f*s:D}Y
myMCL.onLoadError = function (targetMC, errorCode)M i4`}1e
{
zi-e@c7F myTrace ("ERRORCODE:" + errorCode);
&ry:|m+ayxsV] myTrace (targetMC + "Failed to load its content");!Ln0]u-|1Ve*hZ]
} Ay+tG,eEb5h

&JJK#nJ 10. Well that's the hard work out of the way. Now we just have to load the files in to their respective targets, using loadClip, and passing it two arguments: the location of your file, and the destination movieclip for the file to load in to.)X)T8[2a Q9]2[~]wW
10、我们终于将最复杂的工作部署好了。接下来我们只用使用loadClip方法读入我们需要的内容就行了。loadClip方法的两个参数分别是外埠资源的地址和容器MC的实例。
W%V0T:W _l%P| myMCL.loadClip("http://www.yourdomain.com/test1.swf","_root.myMC1");
Y5jwceE5]XJ$_ myMCL.loadClip("http://www.yourdomain.com/test2.swf ", "_root.myMC2");
3X f$kw4u@&P8x myMCL.loadClip("http://www.yourdomain.com/pic.jpg", "_level0.myMC3");
Rf8W:N*~ 8H:F],}v%q'MQ
路径可以选择相对路径。注意,路径的相对性也是一个大问题,当SWF在非本路径的HTML中被引用的时候,遵从HTML所在的路径!这一点是很多Flash教程都忽视的。所以,有时候绝对路径也有绝对路径的好处。[路径问题源文件下载,下载了就一目了然了]'@Ml+l#y F5j'D

Q:^ s~q6h 所有的调试工作最好在浏览器中,而非IDE中完成。而且脚本输出方式必须是AS2。M|+w)k$U4t7A
Remember, for everything to work properly you need to be testing throuhg a browser (and preferably on line so you can see the files loading in real time). You also need to be exporting your code as ActionScript 2. Z#LB(Gn

[.q ZF^MG In the second part of this tutorial I'm going to show you how to use the MovieClipLoader class in a real-world situation, in order to solve a common problem when assigning event handlers to MovieClips dynamically.`v/mU"K+gA
接下来,我将介绍实时调用MCL的情况。为了能适应更多的应用,我们经常动态地为MCL制定工作。J8kV _!~&N e0?&n
#QK |:Ud hv7vx!k1L/F
aw画外音:有时候,我们如此写:
^[z \-Ja q j 1、var mcl:MovieClipLoader = new MovieClipLoader ();
`ry1f*PF P(v\ 2、var mcl = new MovieClipLoader ();$i#i0Hu8Eh
发现第一种写法无法为MCL制定onLoadStart等事件方法。这是编译器根据指定变量的数据类型产生的问题。osflash的一些朋友给了一些有用的观点,我也发现这个问题正好涉及到Flash内部的事件响应机制,不妨介绍一下: aR,kQV
Flash的三种事件响应机制
-SG8`C:]z2V =====jC m|E xG%o
1、简单的回调函数,最老的; v u2eb5F @~
2、侦听器,ASBroadcaster,FlashMX时代;
9]ZyG7O g ~ 3、事件侦听器,EventDispather,FlashMX2004时代
)N)C h/xiFl
T'GC%y n'Che.t 这里,MCL用的是第二种机制,而整套V2组件则使用最后一套机制。
hS2iw3C$`NR 附:MCL官方申明,注意:上述方法中,仅包含getProgress方法!T{M8r`xge3\
intrinsic class MovieClipLoader
8PI.B8cj y_ i-?-Iz { Z+ISWV@V[A
  function MovieClipLoader();
]i`q@!AH
UJ6i,U @/cW q1J   function addListener(listener:object):Boolean; W#x:L-Pn9[,t2a|
  function getProgress(target:object):object;_:O P_q!j8Bc
  function loadClip(url:String, target:object):Boolean;
5P EG eT"O3r   function removeListener(listener:object):Boolean;
a,Udos!i `   function unloadClip(target:object):Boolean;)nqi[`v1Fa C
}1?s7F/fo%{,{
个人补充认为,1、2在不严格要求数据类型的时候可以通用。%[)bQQ+I d9p#@$k
? d.]%s2z
下面开始介绍用侦听器来检测MCL事件的方法。在此之前,我们解决一个最常见的问题,我们经常会在论坛中看到有人这样提问:+]6RM{+`~?ayt7E$k
引用
x$G+`iVa9L~d$h 大家好,我动态地建立了一些MC,并逐个分配给它们一个事件句柄(标志)。然后,我将外埠资源读取到它们之中。但是这些分配好的事件句柄都不工作了!
*y/G?/Zr NnC5F 紧接着,发问人一般会贴出一对乱七八糟的代码,并大呼救命。8xNq r0M`]
A(mEa,a!r0AOT#i
那么,我们首先来分析一下这个错误发生的原因:当外埠资源被载入到一个MC中时,这个MC将会重新初始化。这意味着任何被预先制定好的代码都将付之东流。对于开发人员已经手动在舞台上安排好的MC则并没有相关的麻烦,这是因为任何直接通过onClipEvent制定到MC的代码都能幸免被重新初始化。而动态建立的MC则进行上述的“初始化”,因为我们是在运行中给它们配置的事件代码。
l7tq!}]U3{
sS%q:|7II%Lz'B#g 我们如何避免这个问题呢?其实方法太多了,很多论坛也进行了极为详细的讨论,我就不多赘述了。+~V!['rq6Xy
T:R1@6JvJ
你现在也许还记得刚才我介绍的“读取外埠数据参与Flash应用程序部署是一件非常重要和常见的工作,尤其是我们常常需要检测这些数据加载的进度”
|$R(U5Xj}n 0W(u3j6W6u5H M
我们已经介绍了MCL的几个回调函数,所以这里也不再赘述了。我们现在制作这样一个效果:缩略图标式的图片浏览系统。我们将要从外部读取一些JPG图片,将它们放入我们动态部署的MC中。并且我们希望这些动态建立的MC都具有各自的onPress事件。我们通过在MC装载好外部资源之后再为之分配事件。
dE\ D(?r \W.X? %I~p9HI^
在我们开始之前,我还想提醒大家注意一些经常出现的疏漏:一定要在发布的时候设置成Flash7+AS2以上的版本;其次,用浏览器测试你的效果,而不是IDE;否则你将会得到奇怪的结果。~ p$o+YOn
P2Jd6b2Un"rd M
现在,我们开始编制代码,你会发现它比你想象的要简单得多。
+?-zaL ^0h
Gy,M*`:e rG3} 1、新建一个Flash文档。
.qB5K6j2z~j7t2a
"b3E7SF"Z!W!q_ gP&p 2、找四张100*100像素的缩略图片。
Q)F|7\ J rQP0\
S i K2X)y 3、建立一个动态文本框,大概在300*300像素左右,使用12号字体,并使之现实边框,这样我们更好监测。别忘了设置它为多行的。
:DS t!b&q a:n @l)O3D,|&@.|)s
4、建立一个100X100像素的矩形,转变为MC,然后将它移出场景。这时候,他已经出现在库中了。在库中,设置他的链接名为“img”,并使其“在第一帧导出”。其实这个矩形会在外部资源载入的时候被取代,现在只是为了调试方便。
8v+v+S:W5ZGF0z$E cp;g-t}H:f
5、在刚才放置textBox文本框的层之上新建一层,这一层用于放置我们的代码,先写上
0@J7s6RO/~4F stop();6S.j/\%s_)D-X8v

$F~*@2_%z2R 6、现在我们定义一个MCL的实例,此外定义一个基本对象,作为我们的侦听器:
9w3k"? Xc LiI&w myMCL = new MovieClipLoader(); //define MovieClipLoader
@Sg6M b^p myListener = new Object(); //define listener+xn!@"o,Vad.d
0Ar N d$D0t\
7、接下来我们用侦听器来侦听onLoadComplete事件,该事件的作用上文已经提到了。我们现在把它交给listener对象,而不是MCL实例。当然,最终要把侦听器对象再交回MCL(以侦听其回调函数)的时候,得到的效果就是我们需要的效果了。3O%X0n7\2b;t ~

Lz}-WMD"B c u 记住,只有当读取完毕的时候,对MC部署事件任务才是安全可靠的!所以,在onLoadComplete被触发的时候才部署这个onPress事件给MC:La ]0o9afT|-CY
myListener.onLoadComplete = function(targetMC){6_ @+CS,sn2X
debug.text += "LOADING OF " + targetMC0lT sf3H{&b1Mw&DZ
+ " COMPLETE" + newline;&NT.TRr?
targetMC.onPress = function() {
1q`(J+C9[f"? debug.text += newline
;]\ ZjN9T-D? @;py + "targetMC = " + targetMC._name;
z,h#s_-tR rN,WAm }(~ N zK#@gm;X
}N9_hoD7TBx

#B qvb)E|| 注:上述代码中有几行被人为打断,但这并不影响效果。
7{-q]#J!m
;@^D&i'h(W#G 你也许已经注意到了,MC的实例名称在onLoadComplete被触发的时候是作为一个参数的身份传递给onLoadComplete的,这样我们控制这个MC就非常方便了。比如这里就可以用点击MC来检测事件是否被成功部署给MC。QL"{T [9oY
n^$a^L ]
8、现在我们建立一个函数,它包含一个简单的循环来部署场景上的MC。并且及时地为每一个部署好的MC分配读取外埠资源的任务(loadClip方法),代码如下:k h ]:RJ7~ vF)~c
function initClips(){
"WPQ?)UeG$d V d for (i=1; i<=4; i++){,iA ur^:q&M J
this.attachMovie("img", "img" + i, i);X(P;u]"mdQ:G
this["img"+i]._x = i*110;
2r;U.Cd6vZ y*BS myMCL.loadClip("0" + i + ".jpg" ,
8V!q'w8[?_1Dm this["img"+i]); //code wrapped(dCys&}W
}
(Q?4gk%cNa&N3k }
!{_9_&?2Rc$O a z#A
%]b uFt_K D 9、到这里基本上就完成了。现在我们剩下的工作就是注册侦听器并且按照需求调用相关函数、方法,反映到代码上就是以下两行:
f a2d#gk9M2p] myMCL.addListener(myListener);L.u1K7~lZW ra
initClips();5J-_ S;M+I M(O
&uF)l:wQ
注意这里的顺序,我们的侦听器对象在调用initClip()函数之前就被作用于MCL实例了。现在我们的MC的onPress事件可以顺利工作了,因为当图片被完全读入之后,事件才被分配过去。我们的代码也非常简洁。我们再也不用为了loading而去制作麻烦的循环了,MovieClipLoader帮我们完成了所有工作!,H,jE3v+R9H$MQ

]jc5@ioe[I5? 附:完整代码如下:
Lc6r:^,v stop();
`6vZ8`YJ myMCL = new MovieClipLoader();fJ*q.WB1L9`]%l
myListener = new Object();
E k,|P'pi*W$` myListener.onLoadComplete = function(targetMC)|@+s5[*Pq
{2gKT+v2a0[wR@
  targetMC.onPress = function ()
$n%u7`g;JKK9I3m   { y#g Fz |;p4F7e
    trace("pressed");/jg-`+\ d+lZ:s_siU
  }J"ui)yNV l
}
2uzV]2u4a k
V+u#vbEzO'th function initClips()ZEJy(n'v
{
+X7i/UT8kYwUR   for (i=1;i<=4;i++)
(ky c6yn:ut CnyU   {
&min6a qI^$M#q m9Q     this.attachMovie("img","img"+i,i);5`;C~ O+P4`2L,v5e
    this["img"+i]._x = i*110;(j%|f(j;Z G+[lv
    myMCL.loadClip(url,this["img"+i]);%bF:``s C*W#F6[#H#w
  } b9H2JsN
}}~`wi qg
myMCL.addListener(myListener);{3EK.l(_pbF
initClips();
? T1rt4y)F A d
o3A+@8g,Mrkm;i} 到此为止,你应该相信MCL确实是一个不可多得的好东西了吧?:)
H%GXOX$Cb%W+F*Z
!C4ZGYrJ)v
1@Fy d*Z-p!K$[ ====
J#h6@ ^*}D!L F9kBM!A`g%av
\ ?6vhe
三、含有v2组件相关的问题
:uqs2Z,y:pz}
])QS*RQ ^h1w$p"XA&h V2,也爱,也恨!这里介绍关于含有V2组件项目的loading问题
0k_ vA'QE5S 转载请注明原帖:[url]http://www.awflasher.com/blog/?id=468[/url]
/z9Jx1\ Yw{
3I+b4bP!Q ? cy ?#Y V2组件自面世以来就颇受争议,大体概括如下::a/hdPHi
xk3H+Y!nZPN3@lb
优点:uK{ X;CL8v
·界面比V1组件更加美观、统一,人机交互模式更加完善
yf/X5K*G ·均采用面向对象脚本部署9SQ!^6VWbB
?@'DJ*T A~Bs
缺点
A0br9Ct,C&T ] ·体积笨重,开发一些只用到一两个组件的小应用程序时很尴尬.Y'u8~M2^[ I

3@1D5x7H3K V V 消息机制方面使用EventDispather的消息广播机制,取代原有的AsBroadcast机制。使得刚出来的时候很多人根本不会用。
#yx\ GPGn
HR(]4|3~ 这里就不讨论更多了,先说loading。含有大量v2组件的产品要想见人肯定是不能不作loading的,比如aw's blog左边的那个blog小贴士。然而每次在loading的时候似乎都会遇到麻烦。那就是笨重的体积全部被放到第一帧导出了,这样导致对一些300k以内的,含有v2组件的SWF文件进行远程载入的loading效果变得捉襟见肘。
7a3z*P7[ e%xd o
9py9v:E7D&A Ei 解决的办法也不是没有,简单概括为三个步骤:
u-{,{1T4k(B ^i0s X0K#k}"O)Cc&H,J
一、去掉“Export in first frame”
!v)U[Mk$d0fG http://www.awflasher.com/blog/attachments/200603/24_153106_v2linkage.gif
i iN&hQ]No aM CZ g_^w`
V0K4Y JY6w Q/z
二、在发布的时候设置一下“Export frame for classes”,这一点非常重要!%IX"C5\[sb
http://www.awflasher.com/blog/attachments/200603/24_153056_v2exporter.gif+@,?UUk-N
%W] O ]WYH

0b B6ep7V;^@ 三、对于外埠读取的含有V2的swf文件,将容器mc进行如下设置: [U)LDmp N0D W2T
loader_mc._lockroot = true;
?2K| ?3S2x%Jc? PPy,V4cxkYq'_ d
好了,现在放心享受精彩而笨重的V2组件吧~!gW[ml(Y u#Yr

5G6PVy L%D*hw Gi ~:m 本系列文章:
c"O%gQ8k9K!o 1 - [技术]原创-完美的loading-完美到底[基础]
:R eu"Z"eJuq Z}/rL http://www.awflasher.com/blog/article.asp?id=444
$`H1a0Y/It 结合原理介绍loading基础。
~ZTIs U/M9?&Ia4b {g%n
2 - [技术]原创-完美的loading-完美到底[利器]
J1Bd E0[4U6u http://www.awflasher.com/blog/article.asp?id=468
S Ro0z-e3s0B 详细介绍MovieClipLoader类的使用,以及一些原理。
;faP3|)[/Am1q j[v$piUq
3 - [技术]原创-完美的loading-完美到底[减负]
fq PL8Y7y2{ http://www.awflasher.com/blog/article.asp?id=470@/bR~Xt!g
主要解决v2组件相关的loading,原文附图,至此,系列教程结束,应该不会再有loading的麻烦了!:)

九龙尊者 2008-5-17 19:39

不错啊

设计师 2008-5-19 01:58

不错
页: [1]
查看完整版本: 原创-完美的loading-吐血整理!