草根站长论坛's Archiver

阿祥 发表于 2007-7-15 14:27

Flash AS2 事件处理机制

本教程中你将学习下面的内容:        1.事件处理机制.8j?'r2Y3W0O3o
       2.创建类库.
5u(KI/@*H a%fl.@#I_        3.使用 回调函数.
Xt;}4Zw               3.1.示例: CFEventClass 类(简单的示例).1q4C6?]Lch}{X&w2r
              3.2.示例: CFTimer 类(定时器).
9B `.p F$? W        4.使用 addListener 方法(AsBroadcaster / BroadcasterMX 类).`v*GC'kq:e5hrn
              4.1.示例: AsBEventClass 类(简单的示例).5mC|W$M4{l"Oh
              4.2.示例: AsBTimer 类(定时器).,m']/k2Jl?9c
       5.使用 addEventListener 方法(EventDispatcher 类).
]Lz0Z\9u4T:R(R#s               5.1.示例: EDEventClass 类(简单的示例).
!s!Di]+f&qv               5.2.示例: EDTimer 类(定时器).
+cWTQ*VQ,n        6.建立强大的事件处理机制."X,q1wO/cw]9RAw,b
              6.1.创建 CFDelegate 类(修改 Delegate 类).
|'X)t4q`8SS               6.2.创建 CFEventDispatcher 类(修改 EventDispatcher 类).
Z A!_i:I Wsp(?               6.3.创建 Event 类(事件基类,继承 Object 类).
j&c8XYj+w VG               6.4.创建 IOErrorEvent 类(错误事件类,继承 Event 类).
r!I!Nr cq6M+?.LHL               6.5.创建 HTTPStatusEvent 类(http状态事件类,继承 Event 类).
y)N i zcQa;k               6.6.示例: EventClass 类(简单的示例).
["Bl'M0Nh1|7[e |               6.7.示例: Timer 类(定时器,功能跟 AS3 中的 Timer 类一样). u%kC? d9L(Y&w
       7.小结.
L:M2F@ y v 源文件(LRC 和 CFSound 类也在这):[url=http://www.blueidea.com/articleimg/2007/07/4832/Flash%20Class%20Library.rar][u]Flash Class Library.rar[/u][/url]
:k ny?,Q'e_ [1.事件处理机制]
:Ybk3lq AS2 的事件处理机制并不完美.形态多样.不易于管理.在这里可以解决此问题的一半.本文会先了解和使用
9~7\lN0u.~e6y,]$Y AS2 中基本的事件处理机制.然后建立强大的事件处理机制.来方便管理自己的程序.下面讲解.'H#e'Mi5Ao t;{9^6~C
形态多样的事件处理机制(后面会详细的讲解):1@D JL1cD7iU9g
1.回调函数.(如 onLoad, onHTTPStatus 等)W)x%n*oqt
2.使用 addListener 方法. (如 onLoadStart, onLoadInit 等)
Q5r.ylRd 3.使用 addEventListener 方法. (如 click, change 等)A*~-w0o3Hz
它们的作用域和形态(代码):T3eeU;Wj
作用域是指标识符(如常量、数据类型、变量或例程)在程序内可被引用的范围.
yVD/i R 1.this 指向触发此事件的对象%gJ q,_!tVP
object.onLoad = function(),i?5mq{~1[]zr_
{
zk$xJ`^$ZD     trace(this); //输出: object
b)BZO*k2{E }"VU d(}*W+e8`VlolV
2.this 指向侦听器对象W#D(}X;\ZSzP
var listenerObject:Object = {}; _'|/l_1}0G
listenerObject.onLoadStart = function()
V1t |d#j;u`3l"o"q {9v5IrzDs#D5\8A+O
    trace(this); //输出: listenerObjectC%sW.s1_F
}
[.w3AE6f broadcasterObject.addListener(listenerObject);
'L3oB2}(]-R 3.使用侦听器对象:this 指向侦听器对象
,W k2O@^]Xa var listenerObject:Object = {};N?;Y{*SS"w9ON,x
listenerObject.click = function(evt:Object)t+qk*m/zv
{(T L7lK`n`5c5rj
    trace(this); //输出: listenerObject
aucxp-[0zO} }
#h c jh-A$Miz broadcasterObject.addEventListener("click", listenerObject);GXG0qCOX iu^
使用函数:this 指向触发此事件的对象
,HWh J$^U:o:O function clickHandler(evt:Object):VoidU;o!F6_#l3c,TY]
{wr~,W&p@)?t:u
    trace(this); //输出: broadcasterObjectl2e)F0C LS
}6Zn%W&p:~
broadcasterObject.addEventListener("click", clickHandler);3DBvp hv

%VFp4?%F 有时我们需要更改它们的作用域怎么办?
$c`o6l0a,RC/jbhjD 想要改变它们的作用域,需使用 Delegate 类的 create 方法.5FW.ew g,L
此类的全路径: mx.utils.Delegate;
7_Sf f)B^o 用法: Delegate.create(要运行函数的范围, 函数);
1w6p `%Q m*^.fc\ 例:
aXU vq.udq1h$q 1.this 指向 _level0+U F o)Y8v2g
import mx.utile.Delegate;#v+pw+a-`3]$l3~-W
object.onLoad = Delegate.create(this, _onLoad);
V)N&h.u1Xhna2w function _onLoad():Void
h&m:uq'{4? h {
]Vb'TC%y e     trace(this); //输出: _level0:Y3C r"?ioS]O
} U;c3R8na0C{\
2.this 指向 _level01ClG,{6M @4W qs
import mx.utile.Delegate;
v;?A$y6DtS3x var listenerObject:Object = {};
3pH6bJ+|\N/bIc;K listenerObject.onLoadStart = Delegate.create(this, loadStart);9jvj8Y A y!uR|
function loadStart():Void
#Lo4\/Ci"Ua(x-h c {
V-l7Pb Ms+l     trace(this); //输出: _level0
ry+mv:}B }
z&m4}%h$bo broadcasterObject.addListener(listenerObject);%o}vy"HD/V P-r
3.skf6~W/bc9z
使用侦听器对象:this 指向 _level03R'Rk$AQ.P8\
import mx.utile.Delegate;
&bx"])fq.hh var listenerObject:Object = {};
$Cdc hH Gqy listenerObject.click = Delegate.create(this, clickHandler);
/| G2z"b7tD j+H function clickHandler(evt:Object)
:d#rE4Wz&ls C:t { nRL!f!a;~
    trace(this); //输出: _level0Gi7d"G8^-X'dgN
}
rya]+Q%@4ncT broadcasterObject.addEventListener("click", listenerObject);
`s PD)c M 使用函数:this 指向 _level0 @6Lg&W*o'i Bl
function clickHandler(evt:Object):Void7a6@[U;F/rd5p
{ud-E[{_U HN
    trace(this); //输出: _level0 F$gP SPO*Z+v
}$` \%l+|Qx v7FO
broadcasterObject.addEventListener("click", Delegate.create(this, clickHandler));$X$A{CA
事件对象:5l@h3_*V
它包含两个基本属性:
)}EiL;W;WH type:String              事件名.
"C%C[9C}S target:Object       事件源.此属性可以不指定,默认为事件源(调用dispatchEvent方法的对象).
y8H3QyI%Sq'k 此对象传递给 EventDispatcher 类的 dispatchEvent 方法并作为参数传递到侦听器.r;A Gxo
例:
E6z+k*Z3Os[b //发送事件.!wYy%V tc
dispatchEvent({type:"click", target:this});
Afw~#g.J!o //事件处理函数. ?7^!I-y1U*]k
function clickHandler(evt:Object):Void
qc$?Q&GN/E {
k#Rg"H#Gr p     trace([evt.type, evt.target]);  
9r4h;Q4Y)ML7S };_ j%Upx!CY;b:G
//添加事件侦听器.g \![)j [Z7SBhg
addEventListener("click", clickHandler);
nM|D} U+G| 下一节讲:[2.创建类库]
@(C8k?xP 在开始下面的教程之前.先要创建类库.在硬盘中创建如图结构的文件目录:A9O t2q0E
C3F!N P'Zl'c aRU j2w_
[align=center][img]http://www.webjx.com/upfiles/20070713/20070713111647_01.gif[/img][/align] rq/J#c4{ZZ2bDs
Classes 目录是用来存放类文档.
{@~Gq9D Example 目录是用来存放示例文档.9v1D5P6h%g$D$wm
创建好后还需要在 Flash 中添加类路径:
!wB:~PD\ O r Flash 8: 编辑-->首选参数-->ActionScript-->ActionScript 2.0 设置-->添加(+)-->浏览到 Flash Class Library/Classes 目录.A C Wf Z x
[img]http://www.webjx.com/upfiles/20070713/20070713111824_02.jpg[/img]
&CZv ~.YT_2g Flash CS3: Edit-->Preferences-->ActionScript-->ActionScript 2.0 Settings-->Add New Path(+)-->Browse To Flash Class Library/Classes 目录.
W'N#Y;E}4~;w_ ActionScript 3.0 也要添加(在后续文章中会用到).
0X&].xN/z3sL?E [img]http://www.webjx.com/upfiles/20070713/20070713112027_03.jpg[/img]
%BM[.`KFD 下一节讲: [3.使用 回调函数] nN*C@/] rH
[3.使用 回调函数]1wU ~K[h'VF`
回调函数也可以说是匿名函数,先看下面的代码:
_L7\$kNI s var myXML:XML = new XML();[ D,M+@9cu.@SL)O/zS7_
myXML.load("xml.xml");
%|\+^I:m vh9C&`Zr myXML.onLoad = function(success:Boolean)
#aA?/kg#I"A | {.aPT9Uws"c7m
    trace(success);
J _#t v:Oe5P }
uV j3["Py ^+d XML.onLoad 是一个回调函数.将匿名函数与特定的事件关联,以创建回调函数.函数将在特定事件发生后调用回调函数.
\j+G)S R 在自定义类中怎么做呢?看下面的示例.
;U w%i5a4O#\ [3.1.示例: CFEventClass 类(简单的示例)]7RH Y$MmIU6SA"D(J3a
此示例文档详细:0_h5D {5x%li
Example/AS2/events/CFEvent/CFEventClass.as                           
+iVQ.g e&Y Example/AS2/events/CFEvent/CFEventExample.as                      n IyG`{(oy
Example/AS2/events/CFEvent/CFEventExample.xml                     
&S9E"R6h*Kc Example/AS2/events/CFEvent/CFEventExample.fla                     
3K'U'k"I\ 主类:(U6S?*A0Ia+T
打开 CFEventClass.as  文档,输入下面的代码:
/rWjt/b W3U import mx.utils.Delegate;|*rr6uo_I
//----------------------------------------X_IQa tX(_(z
class CFEventClass
y"R3Zoc*x] {yC+kfr
    //----------------------------------------;s+^)cPcr|:\
    public var tXML:XML;
^H uDWw%O;j     //定义事件函数.
I|On4K1Z+uO z     public var complete:Function;1t2EL"K.pe|N|
    //----------------------------------------
F7s2H8Zi;z Ma.g2\     public function CFEventClass([url=http://www.blueidea.com/tech/multimedia/2007/String][u]url:String[/u][/url])PA(o @(?uyt
    {
tJ FO1y rh         this.tXML = new XML();m`bNH7c:v
        this.tXML.onLoad = Delegate.create(this, this.XMLonLoad);Nx _8U"d$U(C
        this.tXML.load(url);Yt2q#Q1bC7M^
    }$LM;?UD6C+i/io*J
    private function XMLonLoad(success:Boolean):Void
(po&X)V z+e/UQ     {:@ ?(h6]g&U/E
        if (success) {
V)_fWW{!q             //执行事件函数.
2e#A6c[0m{DH             this.complete();SN"k N%E8D;c
        }Z;mh#~-A'm:C/~2Zu
    }
6zZm)TG{ qiG     //----------------------------------------
-TZ$h*^:tS'}g }2V*T'?k$v"p1~x
保存文档,这样我们就创建了一个名为 CFEventClass 的类,拥有一个事件,一个属性,此事件在 XML 文档成功加载后发生.RP]^K_
示例类:
;o {EGe/ql 打开 CFEventExample.as 文档,输入下面的代码:"M}0m [RP^
import CFEventClass;
fc dn9Emt //----------------------------------------v1U,s;o)J z
class CFEventExample~8\ T IyW^_8r
{ WH6t$@JpJZ
    public function CFEventExample()
9kV,LPI$O     {
*b0Enp6N6j         var ee:CFEventClass = new CFEventClass("CFEventExample.xml");}c0M0t8W
        ee.complete = this.complete;q1t$NP*R'z
    }b0bMGO Ra ~KJa
    private function complete():Void
{VB8r R5G     {
;cYr3kWl lU.A2E         trace("complete");x_3@%[2I9x
    }
%z#vog _,i} yD }z%ua4Mj'O.E-F Z
保存文档.
qQ/} DT;g"y 在示例类中我们创建主类的一个实例.来加载 CFEventExample.xml 文档.然后使用自定义函数与 complete 事件关联.;S,O1dDO^'V
如果要移除事件,请使用下面的方法:
s2X?P4}d.Y#s1{8? ee.complete = undefinedmr"l"`-_
//或8xIF:T-nTB&b4s
ee.complete = null;
5k,|_*lE //或JC'z#rv7jnE_
delete ee.complete;
'n6[2K F7U } 要加载的 XML 文档:
Wf6q(r+\'@"F#f_"k 打开 CFEventExample.xml 文档,随便输入一些内容便可.测试用.
h Fv8i!{*bf5@$D{ 示例 fla 文档:
$t?&s cH0b0|a8BW 打开 CFEventExample.fla 文档.将"图层 1"重命名为  Actions.并在第一帧中输入下面的代码:p-Q2k+K/R7D
new CFEventExample();z4^ X _6q K7A1S

2i6J.\m-^u+W 保存文档.
0z6N/y0i9Ua 测试 Flash 文档.在 XML 文档成功加载后会在输出面板中显示以下内容3@"m^Be
complete
p5xI)df'VL?;z#M 如需给事件传递参数,在执行事件函数时如下添加参数:
8^6upg7Z#DH"lYH B9x this.complete(参数1, 参数2, 参数N);
P Z:caY 在调用事件时:'Z6cV.q4k`'d$a
private function complete(参数1, 参数2, 参数N) H5XC%q4c0|O:@
{
G5hVwIr'EM     trace([参数1, 参数2, 参数N]);6]v5ko"?)YS
}
gN6X(s f"T 下面再看一个示例:
B9JPt*gS)` [3.2.示例: CFTimer 类(定时器)]U`8C|!_u/U5Fn
此示例文档详细:-L+l&g)Yq:k+_ M
Classes/AS2/utils/CFTimer.asW}\3w7JolU7[3qq
Example/AS2/utils/CFTimer/CFTimerExample.as0}gOM$[K"g
Example/AS2/utils/CFTimer/CFTimerExample.fla9f,n ^W~]8q1Z
主类:V,Y1g'Y"X B
打开 CFTimer.as 文档,输入下面的代码:
k#L N!K1]]8b0IiV import mx.utils.Delegate;kC0i/Df2hkn(a
//----------------------------------------
9W/c"xL0~_,D+B1X class AS2.utils.CFTimer
.TJ5[2ox3L~'[ {^"b~ Who/A?U`
    //----------------------------------------
O;n I-q3}Q     private var _timerID:Number;{ di+taSF{
    private var _delay:Number;tU L j$vk t
    private var _repeatCount:Number;
pknN@s_m ?     private var _currentCount:Number = 0;+yw0S5|*N kX
    private var _running:Boolean;
v-p zK8m ?z#H-G     //----------------------------------------5a^ d/~.D)t1d5f}g1J
    public var timer:Function;dJWL^an
    public var timerComplete:Function;
Q px%nTs4`/n     //----------------------------------------
)Z~)@2H'{7RKM     /*&L1jsO Na_8{
    @parameter    delay:            延迟,单位毫秒.:W:_ IHf2t K#c2@P$OX
    @parameter    repeatCount:    重复的次数.默认为Infinity(正无穷大);!Py"H0ah*Uo
    */c K],T,c"{E
    public function CFTimer(delay:Number, repeatCount:Number)kr:D!pb ~#X5w
    {
IN:} S;V#QOT         if (isNaN(delay)) {XN.@$F@;VW IN
            return;j[Eoe wn
        }0^9c'bR1Vm
        if (isNaN(repeatCount)) {
~;c+lqf3g BU jb             repeatCount = Infinity;O4uU;?|,Y J
        }
2oQ$s/s#p         this._delay = delay;+UE {W.X
        this._repeatCount = repeatCount;$P ekYTQ
    } Z0?e]RJ mE
    //----------------------------------------U8qq*NU/NwR
    public function reset():Void
7QK,ua%Yt^u;Z     {
-V'B y^~k8~3Q         this._currentCount = 0;9UTM'f U;O&L.xt
        this.stop();t/j:Rw&T
    } M d%R} g&F9U
    public function start():Void dI'uA2~5S
    { t"I\2^U,N5o,O*V4@
        this._timerID = setInterval(CFDelegate.create(this, this.startTimer), this._delay);
0W5YmbQ}         this._running = true;
#aU1sC[x:d     }
%K B1JX5T&N:NX     public function stop():Void#_H I(Y7Y.b5p
    {P&Eq:xK Y P q7`
        clearInterval(this._timerID);
UvVFv-c+w         this._running = false;
\ek6FF#P:zU:Ir     }
h|I1W2GC     public function toString():String&w!hW+iz7V
    {.V p YU|L:Y k
        return "[CFTimer]";
TTAj!v/I&u#U8_q     }U7U/L/X0z6Xr K U
    //----------------------------------------
:}`:~6Bx$n     private function startTimer():Void
EY0{(}0JNW     {
5H6St:Y0nk:A         this._currentCount++;
x-[F#L E/s2o:{         this.timer(this._currentCount);k.`$Lbz8c!Ec
        if (this._currentCount == this._repeatCount) {h}9H,G+m&P9y
            this.reset();7hRS l5L
            this.timerComplete();
mNc%a` }?         }
&OK0I2GFzSL     }XbG"x#n%^7ZNx
    //----------------------------------------
5v kux IY0K     public function get delay():Number
R F J-I _!e     {9@McwQG
        return this._delay;
+E!ym|$q+NB     }3f_I*Mce7\T C
    public function set delay(d:Number):VoidG_)]+SE K
    {p;o*?-l'm"nv:]0t
        this._delay = d;;x nu*rjxQnjf
    }
v1u @!t N"^ y-f     public function get repeatCount():Number x9c*BcT9B~3qu
    {7GTv k?
        return this._repeatCount;ld"t-DEv MR)zR/`
    }
3Fvq0a'P7~     public function set repeatCount(r:Number):Void
T m/V!yKce     {
B&OV$K9S"v9H/K+|"t         this._repeatCount = r; LZC2`_q
    }
8\L C!|S i     public function get currentCount():Number
g:s[6V6U Jb     {+Yqq,My]!m"C
        return this._currentCount;
o6GY2o'^ OK2M2F#X     }3yLRCFB3n0up+i
    public function get running():BooleanG+A$~;~mb7J
    {q uN'Tb f a3s
        return this._running;5A| ls/? Hl2qg
    }I q*Qx3M*m;e
    //----------------------------------------
t k+r1QYV6? }
-f4ukm*LD u 保存文档.K n+[ Ozl
此类的详细信息:3DdqU&} l)U/j9N,Oz.C
构造函数: "pge0rd0v*zu&]0e.q
public CFTimer(delay:Number, repeatCount:Number)
N&{C;V[2H8~ E~ 参数:
m(|6Y+BH6|T%TO^ delay:Number              ---延迟,单位毫秒.uH6y%h(~2T.^H K
repeatCount:Number       ---重复次数.默认为 Infinity(正无穷大);*vG B Y s#[s\/v
方法: X8K(lyU.S#Di w
public reset():Void                     ---停止定时.并复位 currentCount .
;h~ J.JF@!X3pI Q public start():Void                     ---开始计时.
l[t~ZV4R7Ln;t public stop():Void                     ---停止定时.
f.h\3D GF s/]V public toString():String       ---返回类名称"[CFTimer]".
YgUn&i S 属性:L4w [ A"y o:?l
public delay:Number                                   ---延迟,单位毫秒.B5J'jQx+M
public repeatCount:Number                      ---重复的次数.默认值为 Infinity(正无穷大);l&]VogW%]
public currentCount:Number [只读]       ---当前的次数.当开始计时,此值会递增,直到等于 repeatCount.:D*Q;F9Sb2dC \
public running:Boolean           [只读]       ---定时器目前的状态,true 表示正在运行, false 表示已停止.$q7Y+Rz&p@k
事件: @}5s-~b.Y*y%ZN
timer = function(currentCount:Number){}              ---每当时间间隔到达 delay 时调用.Oq1~Ly@d
timerComplete = function(){}                            ---当 currentCount 等于 repeatCount 时调用.
EO-Vw0PvvM7F?9c&U| 示例类:&GHu{OOf r1e&c w'q
打开 CFTimerExample.as 文档.输入下面的代码:$kl wF7Vi`1SJ [1G-S
import AS2.utils.CFTimer;
4u%gO}t5mmqRt //----------------------------------------W6y,{5YDHU:t oa*m
class CFTimerExample3rqM0t/hx)O
{
A}/@!Zr%m&g-K6^-[     //----------------------------------------
+hQEp+z IQ     public function CFTimerExample()7z&fE[E'x
    {
C^/y1^"F3v         var te:CFTimer = new CFTimer(1000, 5);6o3A I7u_p9p`.d3@e
        te.timer = this.timer; B2g0|W'g
        te.timerComplete = this.timerComplete;
n)Zv Tig }         te.start();
4g_J ^E`;TK)u     }6I0?.PG H0qHt2|~
    private function timer(currentCount:Number):Void
UCWk'J5u'hB:K     {
Ne2lXgwf         trace("timer: " + currentCount);
+~ RK W`'@ N     }
"otV\sQ7t3ZH     private function timerComplete():VoidL$aL z3m6d%rC
    {[-B wd_H+S4kv
        trace("timerComplete: ");$F6q#\.F!mo@
    }
FB:o0}m2E(o{3c     //----------------------------------------
KoNo3u!}.P }
Z1V$N7Dw#q/~L 保存文档.
] R4{"xKzY)qE{ 这里我们创建 CFTimer 类的一个实例, 时间间隔为 1000 毫秒,重复执行 5 次.然后实现 timer 和 timerComplete 事件.vf&`k)m`,Di3J @a
示例 fla 文档:!Q:I;UD q8pM}
打开 CFTimerExample.fla 文档,将"图层 1" 重命名为 Actions.并在第一帧中输入下面的代码:+VC9k? Q$`
new CFTimerExample();
3P t:NBb4e\k gy,~ @ag:y\-m1G
测试 Flash 文档.输出面板会陆续显示以下的内容:/At%S5@D
timer: 1Q`~e4x+]$n;b
timer: 2P tR_3\o5?
timer: 3
Fp,iN5d-N1\#Owo timer: 4] Ctl2A+]k
timer: 5!o*n Qw6l
timerComplete: o8]lH&m2cy
下一节讲: [4.使用 addListener 方法(AsBroadcaster / BroadcasterMX 类)]"P je~8Z,V
[4.使用 addListener 方法(AsBroadcaster / BroadcasterMX 类)]
Wq pRa&G o{ 在 MovieClipLoader 和 Tween 等类中都用到了 addListener 方法来注册侦听.
c;llbR~-O/Y 我们该怎么用呢? Macromedia 为我们提供了如下二个类:
Q;O&S%~ r AsBroadcaster 属于系统类.G CB`Jb"e
BroadcasterMX 属于自定义类.类路径: mx.transitions.BroadcasterMX
$~i Hvg rPJ 这两个类的很相似.它们都是提供事件通知和侦听器管理功能.
})KB2gc6n,G^q 但 AsBroadcaster 类是系统内置的.执行效率会比 BroadcasterMX 类快很多.所以这里我们就用 AsBroadcasterAl!~H,y] u
类来讲解.
3~:a7pD7W g 此类详细:U'C?C&@-QDX
public addListener(listenerObj:Object):Boolean         ---注册侦听器.
K#T%@ AoE)N public broadcastMessage(eventName:String):Void         ---广播消息/发送事件.
L QK3?/Ij u(|l/RX public static initialize(obj:Object):Void                ---将事件通知和侦听器管理功能添加到给指定的对象
:bBm2dy[ V&L public removeListener(listenerObj:Object):Boolean ---移除侦听器.
_k] vA%X public _listeners:Array [只读]                                     ---对已注册侦听器对象的引用.
lxW9O7I:d(p!g 该怎么用呢? 看下面的示例:
}d;DDETL [4.1.示例: AsBEventClass 类(简单的示例)]
`.iN@nx 此示例文档详细:9H Q6V,BRT3czID p
Example/AS2/events/AsBEvent/AsBEventClass.as5F ^8_N1i+l r7J[iI
Example/AS2/events/AsBEvent/AsBEventExample.as5Z#ZUI&Yo!y,X
Example/AS2/events/AsBEvent/AsBEventExample.xml0m!i.G?5m5l
Example/AS2/events/AsBEvent/AsBEventExample.fla
O.kMh8rBY 主类:
6hx+KV5i,@_ H/] 打开 CFEventClass.as  文档,输入下面的代码:R b.M%t$@_{
import mx.utils.Delegate;#lm:Q1P5Sj(z |Y
//----------------------------------------
&k,K w!c$ZkL+?W{ class AsBEventClass extends AsBroadcastere2E4E_4b?0JUP
{
/K/_] }[     //----------------------------------------*fw4R+@s'X#P n/D
    public var tXML:XML;;x$p^2s^@K-j'`
    //----------------------------------------
GLtP&cc sx     public function AsBEventClass([url=http://www.blueidea.com/tech/multimedia/2007/String][u]url:String[/u][/url])Xt.Is;FAl
    {
hZJ-c2{4\ ` ST         AsBroadcaster.initialize(AsBEventClass.prototype);
1W8D~0A e2[#F y L         this.tXML = new XML();
&U Dw!B(e+C'k5v%\         this.tXML.onLoad = Delegate.create(this, this.XMLonLoad);KJl)v+? lx"?8F
        this.tXML.load(url);+w2\&Q%KKD.tzvn/_Y
    })Eq.nGl(\:ZB
    private function XMLonLoad(success:Boolean):Void6pJ)A g-yZ*i
    {Tyj&i8_Z!|
        if (success) {7E i&N~%jn
            this.broadcastMessage("complete");ZnI&d'Q%y
        }
/{S }i?1Ki }     }5J9Ya;n(}v1VQD#@
    //----------------------------------------
ai HW%c(V }IX7qV?^T
保存文档.U(}me v df
这里首先继承 AsBroadcaster 类.然后在构造函数中使用
,\.h7GN9m3B AsBroadcaster.initialize(AsBEventClass.prototype);.F7{%_%\&Ek
来获取事件通知和侦听器管理功能.最后使用
}N#~B5? Ji%P this.broadcastMessage("complete");
B i~ JA]X.N 来广播消息或发送事件.
Wwv.Q*TH*_ 当然你也可以选择不继承它,但需要在类中添加下面的方法:
'S0r Td@.Sh |)v9e,K public var addListener:Function; Kc(X%f+HP9{
public var removeListener:Function;
3`n;O,Fl j%eM private var broadcastMessage:Function;
8}GZ b*\hp4wD6[ 示例类:
xv/n#?Y0dM8ntq 打开 CFTimerExample.as 文档.输入下面的代码:
%E-O if;`%V3\L import AsBEventClass;-N(wFR8] uR4j N0G
//----------------------------------------
B en;^y p/}Y class AsBEventExampleN;n1w?(O9mVvL4u9O
{
"Zto][k&t:@5}     public function AsBEventExample()R!`-d3D4k
    {G\K%|3~+F
        var ee:AsBEventClass = new AsBEventClass("AsBEventExample.xml");
*C.QT:V w P!M7U#aS a         ee.addListener(this);
mk.S/yH     }
~fu oJf     private function complete():Void
z2u$U L7b6]&w     {
g#n[$]Uv+v6B/Br         trace("complete");MTE.|9P(C#x YT c'rB
    }
XKW b"z6]1Y }
Icu|Z9G 保存文档.;mJ2w/HVE]%D"jvW[
在示例类中我们创建主类的一个实例.来加载 AsBEventExample.xml 文档.然后添加侦听器.~8O(vVPc9f;K? kI
如果要移除侦听器,请使用下面的方法:
c6^'BU.i:O ee.removeListener(this);h&T8QXmO
要加载的 XML 文档:
MQ%]H*C4m:? 打开 AsBEventExample.xml 文档,随便输入一些内容便可.测试用.
#\9I.dk0CiR7h 示例 fla 文档:X#B2c2esJ2e
打开 AsBEventExample.fla 文档.将"图层 1"重命名为  Actions.并在第一帧中输入下面的代码:k^,n,c7kzW*A*?*Ab,S
new AsBEventExample();
'O%S#NAl_ vl 保存文档.
K,TYZ@)V[%Y~T 测试 Flash 文档.在 XML 文档成功加载后会在输出面板中显示以下内容Fg#oT!B|
complete*UBW:z/f%H/|[
如需给事件传递参数,在发送事件时如下添加参数:,UEfM:wR
this.broadcastMessage("complete", 参数1, 参数2, 参数N);u,\^lCs
在调用事件时:['_:lM[
private function complete(参数1, 参数2, 参数N)
*^+k \o-XLR!@ z {
{:`4U+F(q     trace([参数1, 参数2, 参数N]);(oP0h/G`"{!Z
}
$k,GEi dm0K@ 下面再看一个示例:~ D+a"bY@-ln`s"N
[4.2.示例: AsBTimer 类(定时器)]oc0S|ESsMp1J]d
此示例文档详细:
/C?X&X!} Classes/AS2/utils/AsBTimer.as
3^:cwLBc Example/AS2/utils/AsBTimer/AsBTimerExample.as-A5q F RUjh
Example/AS2/utils/AsBTimer/AsBTimerExample.flapr }R E
主类:
;^7\b7k9o 打开 AsBTimer.as 文档,输入下面的代码:| y;Z)C@;x.D!h
import AS2.utils.CFDelegate;8]|FAPO/X"I
//----------------------------------------
I#{{"u [%` class AS2.utils.AsBTimer extends AsBroadcaster
!WWY`8le'|_I {
f6pw3I @dj     //----------------------------------------b5Q*o1X$\ M
    private var _timerID:Number;
L"| p*q4i     private var _delay:Number;
z0wq@em8R)P     private var _repeatCount:Number;
u {*nE'PQ     private var _currentCount:Number = 0;}$QajEt
    private var _running:Boolean;
0lqYIb(GhF {     //----------------------------------------
#}z_H A&A._     /*6?s4ek:m+YO*N
    @parameter    delay:            延迟,单位毫秒.8V R.oa _*L(A)s:SW7Z
    @parameter    repeatCount:    重复次数.默认为Infinity(正无穷大);6n6lG!X.GE,a
    */:rF'nn|5p4_3Q'@9C+Y+G
    public function AsBTimer(delay:Number, repeatCount:Number)
d4Pw/DmJ     {
JYR w|,r7xJ         AsBroadcaster.initialize(AsBTimer.prototype); n&VD/S2x4g Gm
        if (isNaN(delay)) {
*m:UCQ0? @             return;n{#F9S#d k|o1}
        }m zrJ0_+C|'nGI([v
        if (isNaN(repeatCount)) {(Y;Mf,kgceq9E
            repeatCount = Infinity;
lVKX!gq&x x2Q         }
t!z[IpMC3D         this._delay = delay;
%V.j1G*k4MZ         this._repeatCount = repeatCount;9NE lI.i7G&W7|x
    } l0u @5Nf"g }*G
    //----------------------------------------
{Z0yz kO     public function reset():Void
9wf c E IPS     {~0^/RX/@
        this._currentCount = 0;G*f9N"R[
        this.stop();
4f7s},X.|5Mb%j%@;M     }
ISNtYUd     public function start():Void
[m`S6A)dr     {
P/eG6eF _ t W6Wa         this._timerID = setInterval(CFDelegate.create(this, this.startTimer), this._delay);#B2k7Jx0l h
        this._running = true; W0a2\l id#BDN6J
    }
Dx@*gZ4S.GS Y     public function stop():Void$q,C N lDS5y)X
    {
Q o&W7wv{         clearInterval(this._timerID); \$u5]+C PC
        this._running = false;1J,bBAU W~*V8E
    }e6h@%`Dsh
    public function toString():String
H:f4K[[F:F$p     {
2zDev}5y         return "[AsBTimer]";
nQ/J)c1EQG     }qp6[^/c1UK7m
    //----------------------------------------
`3_sw"GYSx     private function startTimer():Voidkr*?)f+hz yZ
    {hVWx^
        this._currentCount++;?/{+u+r+g!{+?*O1G)E^
        this.broadcastMessage("timer", this._currentCount);
Ju Fy-vs         if (this._currentCount == this._repeatCount) {Z,q9@fK
            this.reset();
Q%y%UfJmD*X             this.broadcastMessage("timerComplete");
P&dBs~ I         }W } C_"XyZ$D.zS
    }
)F }1_dg;]^6Y     //----------------------------------------F8\s9b!R/K^
    public function get delay():Number
b'@:H"M M&I     {W_/y;})s|
        return this._delay;-C8fH-[;eY j u
    } _z8YQ"nfvk,X0R
    public function set delay(d:Number):Void
x&n:gRd2St     {-~G"I'x$a
        this._delay = d;8Ul$W1?*\H8CA
    }
'A8|BM0c+F#t     public function get repeatCount():Number
{'{*|3qv r)\2BTR     {*A.t?_;T}Z:i'y#Q
        return this._repeatCount;
O2@8^}g5Q     }
5S+]&]]!{ Q Xx9~     public function set repeatCount(r:Number):Void9C&DY7[$` @%^0L
    {nZ0Q'XxJ1J%T` _
        this._repeatCount = r;8{ m$I3F0I1B6GL(W
    }
p'U+^F+cc     public function get currentCount():NumberOp'X m7fjwN
    {
,e$[E9Vw^y*V         return this._currentCount;gY$S5DGjz:lEh
    }
9},\V ]$P0D5|g     public function get running():Booleanhh8w8k#fc
    {p:L'},Urf C^t
        return this._running;
o| f:ox     }
8?%s)rq@&~nh     //----------------------------------------
1tXPm.L"N8m8{ p }KSxBY r$^ N4Cc
因此类详细前面已讲,功能一样,只是事件处理机制不同而已.这里就不再啰嗦.
T3R&i0{"Y 示例类:
Tnm:k DW 打开 AsBTimerExample.as 文档.输入下面的代码:
Zo}W/C)U,C1d6^u j import AS2.utils.AsBTimer;
u^#IfC+B //----------------------------------------
)XK/GtK)by5s class AsBTimerExample
S:i(m{3q p(~B {j/GD$[7[b i
    //----------------------------------------3CslhhedL
    public function AsBTimerExample()p C0T9y:p,F"Q+r5c%V-HF
    {F {EwU$[k ?
        var te:AsBTimer = new AsBTimer(1000, 5);
.bC&XLK R         te.addListener(this);w3UxtG\F%v
        te.start();
#JT({P$nO R&o u3f#@     }
L b4Y5gb9F{     private function timer(currentCount:Number):Void
l6o*S.Q#]K]f-L/lPd     {
4_\(GRv7J s4Jq         trace("timer: " + currentCount);s&Q+vaO9I{vu3QD
    }
6mHk9V:C     private function timerComplete():Voidq0ni w~ kX
    {'tJ%x/jjO;{ q
        trace("timerComplete: ");
BurH4[%ex}Nr.m     }
L w"s9|tH!V     //----------------------------------------:E8p6l~ \[ a Q
}u?&T"E6~T5L[
保存文档.
W D-LF+S.M%e'Ul 示例 fla 文档:
k5fqf5r8h 打开 AsBTimerExample.fla 文档,将"图层 1" 重命名为 Actions.并在第一帧中输入下面的代码:
3M,@tl wb#k new AsBTimerExample();
dU2B y4KU y 测试 Flash 文档.输出面板会陆续显示以下的内容:Za^+B7n(T+L
timer: 1:B{?#QBY
timer: 2
%d|g%Q2?3Su timer: 32j6f']qB5G1Io
timer: 4RH8R0J0` G:{1g%|
timer: 5X N+A@i&u?g
timerComplete: ,|yfU"S:R f7t
下一节讲:[5.使用 addEventListener 方法(EventDispatcher 类)]\mw6~P,L WlJf
[5.使用 addEventListener 方法(EventDispatcher 类)]
Ns8]{ |
H7Q?5E3G4v 打瞌睡了吧? 貌似有口水流下来了.呵.本人文字表达能力不是很好(好像是没吃多少书).让大家见笑了.其实学编程8W%E[7U?|2Nl
是比较闷的.不只是闷,还有很多很多,但既然选择了,这些就只是学习途中的坎,需要我们跨过去.就像是你选择走哪
d_ Xt+} |3L 条路一样,既然选择了,就必需是要走的.但这路不只是你一个人走,人多了就会有竞争,我们不能总走在别人后面.所mzW+iAEz E U
以需要加快脚步走在前面,让后面的人去追.但有时也会在不知不觉中走弯路,我一样也会,所以在本文中如果你看到7i u1Y3C\$B(y
有不正确的,希望你能指正,谢谢.此文的目的是想让大家在这条路上能走快点.你很啰嗦呀....呵.题外话就说到这.
ZJ%^!q6FlU 下面继续.
0\zg&cG.Z\^o 这一节讲 EventDispatcher 类.此类也是提供事件通知和侦听器管理功能的,但比前面讲的功能会强一些.在 AS2 N]0m\(a{A
中,此类用于组件的事件处理机制中.因 Macromedia 没有过多的讲解此类.很少人将它用于自定义类中.本人在研究L"X3yC6i*^"}/n3tw
mx包下的类时才知道此类的用法.4K-k,]hw!i_ ym
首先看看在组件中如何使用:3\8iIMPD]d h)V"d
1.J _(R!w0El8B"C
function clickHandler(evt:Object):Void
q6`-A3U T qZ["uA"Z {
k-Q0Z9_h+Al_     trace("click");
/V)Q;[8{*yvQ JA;U ]3`$iA]1y1hXAy2}
button.addEventListener("click", clickHandler);
b_*pg(jL 2. }5T%tN$w`
function click(evt:Object):Void
w WQB`#G"s;d8} {
Hxl7vv9J     trace("click");lHeny9{ B[
]
xU h0UIAr eX button.addEventListener("click", this);H_g#ZP'_
3.&j7i4Xa+O.nC.o
function handleEvent(evt:Object):VoidG+p m*no)Gv7Q*H
{KuR&hL'Z!C e o_
    trace("click");
/D3|%?0qP!vb| ]
fqX'`:U3Z,`)K(?:y*z1LN button.addEventListener("click", this);.Q_n(n;O`e DN
4.1Xg#mO&G k Z
button.clickHandler = function(evt:Object)
"Ft+U"mS+erz,G {
dH&C `Y|_1`;}Qc     trace("click");
GtUVj }
}6\wf W}8X8\;O 这几种写法其效果都是一样的.都是侦听 button 实例的 click 事件.C0z0\Z:s!CL8`M f7A
下面来了解此类详细:
+G6c ~%T1P public addEventListener(eventName:String, 侦听器对象或函数):Void              ---添加事件侦听器
Eli5[)xB [!mz public removeEventListener(eventName:String, 侦听器对象或函数):Void              ---移除事件侦听器
ReF-R*qLVG7D public dispatchEvent(eventObj:Object):Void          object:Object):Void 帮助文档中没有讲解 initialize 方法.此方法的功能同 AsBroadcaster 类的 initialize 方法一样.*J*~ }/gs1jtL
该怎么用呢? 看下面的示例::Nm%k$foA(W#j(U
[5.1.示例: EDEventClass 类(简单的示例)]7N%D5a3VJ`(z
此示例文档详细:nu3dpW,rE:o K{
Example/AS2/events/EDEvent/EDEventClass.as
N&Ox u)Y1nih Example/AS2/events/EDEvent/EDEventExample.as,M$s$u%I3uH:A+ifNO
Example/AS2/events/EDEvent/EDEventExample.xmlVH`2|Q[
Example/AS2/events/EDEvent/EDEventExample.fla%f&q3m/uz,H
主类:
^Qd-y ~0L 打开 EDEventClass.as 文档,输入下面的代码:J E0i-Ve'S.j
import mx.utils.Delegate;
F d6|k3q-N\EH import mx.events.EventDispatcher;7O1V;G(z ]S
//----------------------------------------rnS ? V{L!gdo
class EDEventClass extends EventDispatcher]&h(|!gD5l1T [k
{g1Fvl0v*AS?$X
    //----------------------------------------4g {cz Q'AA
    public var tXML:XML;
(?H&KJS"{     //----------------------------------------#C(DU$i0``_{6MS#f
    public function EDEventClass([url=http://www.blueidea.com/tech/multimedia/2007/String][u]url:String[/u][/url])
)cs+s(P/yw^     {
-EDI*T@9nVv         this.tXML = new XML();xzD!Ty1Oy
        this.tXML.onLoad = Delegate.create(this, this.XMLonLoad);zei+O1UC"z}
        this.tXML.load(url);@5p,v@5hlE x+e&I rY
    }E TdvG6? t
    private function XMLonLoad(success:Boolean):Void/edv0@di PE
    {-Rbd awH&I bJ} S
        if (success) {
o-a2r:Rm#c(w             this.dispatchEvent({type:"complete"});*H&hC:|`
        }
0j_ z2?+mo/cn9n     }
9~j NI"f?9F!h     //----------------------------------------2D$L3z3tFM9^Z
}W+xk^#g
如果不继承 EventDispatcher 类.请将代码改成如下::]EUv,?n$O0wp G
import mx.utils.Delegate;9hXaxTI`
import mx.events.EventDispatcher;
*l#f:fqn'r+sR //----------------------------------------
+r:sMx|&f U class EDEventClass
h8zTu-r'U0c {:ZxSL+_"u)Cf-_W
    //---------------------------------------- ^%Fy;g C ve9fnZ
    //不继承需添加这三个方法. v:qOquKq
    public var addEventListener:Function;
_,G3eVxGf0|     public var removeEventListener:Function;CDc?6e6@
    private var dispatchEvent:Function;
kh!SAT     //----------------------------------------%b\!XbSg B-S)h
    public var tXML:XML;
$T] ^/P5S(MQ^gFjM     //----------------------------------------
$aW Va2B     public function EDEventClass([url=http://www.blueidea.com/tech/multimedia/2007/String][u]url:String[/u][/url])q1o J!bQm)kv
    {
PqnuE9u.oJao         //还有使用 initialize 静态方法.
`^FvNvPC W         EventDispatcher.initialize(this);.@fq-Gpx5C
        this.tXML = new XML();F4E\~`.z:f5K
        this.tXML.onLoad = Delegate.create(this, this.XMLonLoad);%Jo*zvb-S!n
        this.tXML.load(url);^-p,A+nxjM
    }
"Ped \vW`     private function XMLonLoad(success:Boolean):Void
6F va+{a'x5R3X     {%v1pTNy,{"m.j7L
        if (success) {+w(jt ]I-q!O
            this.dispatchEvent({type:"complete"});
$I3w#o0p ])Z} {         }
D6_~/\lw9QV3B i     }
'o)T8b!r7[     //----------------------------------------N k3{9Fb(`[#w)Do5g
}:sd ^-GY
保存文档.
O-iUz~w1d(S Uw 这里首导入 EventDispatcher 类,你可以选择继承或不继承此类.上面的代码一个是继承,一个是不继承.区别/qr)X rz(R I:JNq
也很容易看出来.这里就不讲了.
*Vyu#ac*f4[Q 示例类:
?JK sK-H*h 打开 EDEventExample.as 文档,输入下面的代码:
%X9[)wImi import EDEventClass;
Nc]D+f"WWm/K$r //---------------------------------------- q#RI Ir![p2As
class EDEventExample ~D'D3~;[ q
{
+VO*m)oSh8j}C     public function EDEventExample()
c+WeCj?F2aZ     {
[yc:zx/W.K\%b         var ee:EDEventClass = new EDEventClass("EDEventExample.xml");RQ1pcGv"b
        ee.addEventListener("complete", this);
6X.Rw bU c     }&Mcu5O3K(|#g
    private function complete(evt:Object):VoidR,c4I"w.Cd`
    {d{p,~+\0`]/E#JCG
        trace("complete");
Zz o5B5^+J/h8}}     }
Y1i9D~(C~e }
!vE2He:jWG 保存文档.0xw6RE }6c
在示例类中我们创建主类的一个实例.来加载 EDEventExample.xml 文档.然后添加侦听器.*e5b{8Qk YN
如果要移除事件侦听器,请使用下面的方法:9{ C Ig BA gb
ee.removeEventListener("complete", this);N4Q)cS!u-ikH
要加载的 XML 文档:2~r5F*u9Dn)\)U
打开 EDEventExample.xml 文档,随便输入一些内容便可.测试用.
Z J#hb x+?g4l 示例 fla 文档:'D DXo`)o
打开 EDEventExample.fla 文档.将"图层 1"重命名为  Actions.并在第一帧中输入下面的代码: Wx"Y5pY.`V
new EDEventExample();,UPtoqe\:no t;?
保存文档.
!EE#G[A3}Hy 测试 Flash 文档.在 XML 文档成功加载后会在输出面板中显示以下内容%PV,M,|w
complete
5Z;WE1Z1V)j:C 如需给事件传递参数,在发送事件时将参数添加事件对象(请看:1.事件处理机制)中,如下添加:lL)M/D3sD
this.dispatchEvent({type:"complete", 参数1:"参数1", 参数2:"参数2", 参数N:"参数N");;P,FG q&lO5s-V.C7|
在调用事件时: G!Bq8b p dB
private function complete(evt:Object)
4f7@9H S xWn2wu l {
dX {rYrH"Wc     trace([evt.type, evt.target, evt.参数1, evt.参数2, evt.参数N]);1nP&jB'^9fuP)L(@
}
eU/Z!rxA z 下面再看一个示例:
:bg$lU,_b:? [5.2.示例: EDTimer 类(定时器)]
7XUM \3w*u9lM 此示例文档详细:!wBl6x;x/QE0[#D
Classes/AS2/utils/EDTimer.ascjV0S{&{Fb
Example/AS2/utils/EDTimer/EDTimerExample.asixUGM.y-u
Example/AS2/utils/EDTimer/EDTimerExample.fla
2j)z%A0qY~2~? 主类:
,Lt1[iU6A 打开 EDTimer.as 类,输入下面的代码(当不急时,应多打代码(有利于巩固知识).不应 copy/paste):T~&Vx2[1s*K
import mx.utils.Delegate;
U'gT1F+d,Z:T import mx.events.EventDispatcher;v:UFP%|X8p.Gp ^
//------------------------------H7wH ~%?@ V
class AS2.utils.EDTimer extends EventDispatcher
F3sZl j {6[-n"hB.d\2D'~5M
    //------------------------------
d,N{$h3g     private var _timerID:Number;
"V.A/\Fv'e6S     private var _delay:Number;hO(q"A/k[
    private var _repeatCount:Number;
-] WQ A;L     private var _currentCount:Number = 0;
3Q;B#P{%I:KL@     private var _running:Boolean;#E@h}1ix
    //------------------------------ N)_pE.ba YU
    /*U^0sC;V
    @parameter    delay:            延迟,单位毫秒.$P8YN"uj6@
    @parameter    repeatCount:    重复次数.默认为Infinity(正无穷大);
5{0dm+B MN     */
3g4P"q(m9m!vr     public function EDTimer(delay:Number, repeatCount:Number)^P2G_n;D\/N8D/Q
    {
m*e F&N!b4ZBf         if (isNaN(delay)) {
a7s8X*AV             return;Ox|+kA;y.Y&pk;`[
        }"bw2VR hAm
        if (isNaN(repeatCount)) {
P+X#VG5\~ f;q*u             repeatCount = Infinity;
'W5XY f;c"p7jd!MB         }
8r,aZ^ Ou m         this._delay = delay;
qZ2HH[3Y%C         this._repeatCount = repeatCount;
z t.k2G^;P     }.P)B9};]ai
    //------------------------------
"w3j dM`4p8Q,WsP6j|     public function reset():Voidq9M"Aw]
    {
XqbX6d]X#G |"i.j         this._currentCount = 0;
#aB*|3I a"W?$e         this.stop();%MC{M @C-KJJ
    }[x.Sp b
    public function start():Void^on*]-N,ewl
    {Pb9S)M)k6e
        this._timerID = setInterval(Delegate.create(this, this.startTimer), this._delay);MuX x%O-r
        this._running = true;
\}*k"~o+d#k kA     }
-e3`\U.g&_E/i     public function stop():Void+L MDAx;g
    {
a~5PR.O8Xz|         clearInterval(this._timerID);
6?3@bp sb         this._running = false;
+L`g"V6o^     } K)P iq{R$\q
    public function toString():String
2iae$kK8W&W     {'S*q9t6~-e,s#c
        return "[EDTimer]";$R@b;KN3A"{N!|
    }
@l-h7g(g&W9u5T7n     //---------------------------------------- gVY:Fcf(Rbt
    private function startTimer():Void%@kA [S8vq
    {
^ fgc;v MY         this._currentCount++;
^!Hp1k*c;mvG         this.dispatchEvent({type:"timer", currentCount:this._currentCount});$o-iLG3wQ
        if (this._currentCount == this._repeatCount) {
r?.t#`K             this.reset();
Cvz3F0^             this.dispatchEvent({type:"timerComplete"});;h5a)~p0Qe)X4p9z
        }
"wt}0IIF/C7o     }nv vwO|i
    //------------------------------#BD MCr
    public function get delay():Number
`N2y(zbD P C!H ]     { fs0]\.x4xV9g]
        return this._delay;
jrlW8q:[0P     }2FC Im1M'V5{
    public function set delay(d:Number):Void p1[*{3~}m
    {
;y,r6[-^$UwK2|         this._delay = d;
OHI_)ok$I     }
*]inK:EXhF     public function get repeatCount():Number(t2X,xcsNz(M R&L
    {
#^)a5a/l%eR#L-L G;{         return this._repeatCount;
swN/{;U@'XKp     }e0A,N5YLbMgA
    public function set repeatCount(r:Number):Void
XFsC"r0~@4z|N     {
D {M:^4Q)t,~+F;W         this._repeatCount = r;
&t6p)g k9VQf?C sP     }*UI/etYPrfp
    public function get currentCount():NumberAf#c5V&x7{ W
    {t7~6C Tjep'["`
        return this._currentCount;
qk+vc"o     }
p/p`%w-i+[Q     public function get running():Boolean'oV'w Vz W
    {H?sE Xh o'b
        return this._running; jl(P0k%[8tX:|
    }#mUy:F!f_ y
    //------------------------------
er$hz~ }&i:W }
4kVkvH-M 因此类详细前面已讲,功能一样,只是事件处理机制不同而已.这里就不再啰嗦.
)PuZ~*G@ 示例类:J n)cNLg
打开 EDTimerExample.as 文档,输入下面的代码:
a!{4rd i3C;w import AS2.utils.EDTimer;
-l,G+~U]&J$I-\ //----------------------------------------VhWP8X1v.Q
class EDTimerExample'w`:V*U t,fj _
{5nH/RtL h B+O
    //----------------------------------------_?M5|*U
    public function EDTimerExample()[cw.EY9a?n H
    {w+mGy$b/fX
        var te:EDTimer = new EDTimer(1000, 5); AI%L*Hfr)wD*SB
        te.addEventListener("timer", this);
h lyJ"^H#[         te.addEventListener("timerComplete", this);
,X6}$A-Q u[/Tz         te.start();H2oQ!L5Z%l
    }
!AKV7f#JACa&q     private function timer(evt:Object):Void
"b J/J$C0?3^     {^%xx#N4E(uav8M]
        trace("timer: " + evt.currentCount);9G9ow#bz,MXR
    }
#I#D7`p f[,l bj     private function timerComplete(evt:Object):Void
Fh@]W6H$?&t     {
\S0`0a9o j|         trace(evt.type);
g;S(Xz Y9yD     }
LS qv'S w7|W     //----------------------------------------*KI*j2TsE#M$skx
}
!V+W0v#t"uku 示例 fla 文档:
n/fg7MaZ%Ci 打开 EDTimerExample.fla 文档,将"图层 1" 重命名为 Actions.并在第一帧中输入下面的代码:$}]$L a*c
new EDTimerExample();'i+sPc$W`
测试 Flash 文档.输出面板会陆续显示以下的内容:
c7]}a&\z Q&t timer: 11jw/gf-H2A9W
timer: 2F8e#q;`/]S*y RyI
timer: 3J*bE)n-]#dg2}8m5@
timer: 4 fLi%OD~p|$j
timer: 5
j)H&CIsz timerComplete
5w9H'Mz%AF/e(b 下一节:[6.建立强大的事件处理机制]uf0|NMd-d
[6.建立强大的事件处理机制]
J;y*g UIj o 这一节讲建立强大的事件处理机制.学完这节,如果有接触过 AS3 的,马上会想到一句:这不就是 AS3 的事件处理机制吗?OeP1_"Y;WP
的确.可以说跟 AS3 的事件处理机制一模一样.但还是有个作用域的问题.这节对想学习 AS3 的事件处理机制会有很大/c F8Q%egD AO d
帮助.如果你掌握这节中的内容,在 AS3 中就只有语法问题.也就会很快进入状态.毕竟是"水往低处流,人往高处走".对现
%LoT b'ZP)K 在用 AS2 的,学 AS3 是迟早的问题.不过 AS2 在新版本出来之前还是会很有用的(个人的看法).,P}!@,N;N j2c
作用域因为一样,前面也讲过,这里就不在啰嗦.
.O\n7Yq+~w V.{)F/k 事件对象.这里已经创建一个 Event 类(或其子类)来代替.但功能一样.5dC6h6i]k%OT
这节讲的事件处理机制的形态(代码).
0wgU[S 发送事件:7L5uu[O z6y~8\
//继承..`+hQ+\.Im'V O^T#Z v
import AS2.events.Event;
3^a"T7~vF import AS2.events.CFEventDispatcher;h/P6to%mVg
class className extends CFEventDispatcher
y:j[GY;ny-hJ:y {r1L}w6i$f-A
    ...
xz!b'@B.iV!kx     this.dispatchEvent(new Event(Event.COMPLETE));
T%uC-uL     ...e8v9iIH5]T#L
}!u.CF:L%o:z^
-H!HPG"xRC
//不继承.
)O h2Nu:w import AS2.events.Event;'Ql4G&LY.Z
import AS2.events.CFEventDispatcher;
tU8c-M q~4_ class className6lU%c@2O;E#| V,?
{ZB#be Pxr C7D
    public var addEventListener:Function;
;Z A4D4K6H,V$Yd E     public var removeEventListener:Function;ke k5x`;Y
    private var dispatchEvent:Function;'Fbhmm8\:|
    z/H P-f5Q&b2c
    public function className()!m}'a&N7T]]
    {)\{![4U!OP
        //此方法要在使用 dispatchEvent 方法前被执行.一般放于构造函数中.;u!};^:J B)d d
        CFEventDispatcher.initialize(this);&J5|,{/I?w
    } \[-gr[
    f ](hj(mB$V
    ...uA&a6MM
    this.dispatchEvent(new Event(Event.COMPLETE));(n1Zd0qx|6r.u
    ...c.xqqPj
}"]2~E\E^+R-d)[O0`
侦听事件:/{5aF f0Mpb e[*Z
//使用自定义函数.(t7WR I/`T(U/N(T z3B
import AS2.events.Event;
(c iP&Osp3k+o import className;zU!W!S(o-N:D-Q8`
...
a,Ds'R B)l u] var cn:className = new className();
#c0n3X:s-|#{$D7k //自定义函数.
)Afdvsg)Y~*l i function completeHandler(evt:Event):Void
(vv d ZrL ` { [Ouj'sp6L ];n
    trace(this); //输出: _level0.cn5byS6ij9LwZN
}-r db5M:[U)lC
cn.addEventListener(Event.COMPLETE, completeHandler);
.wW2j8^_Ww ...iAtTZ)y|
0vEY@ KViW
//使用事件侦听器对象.
n#? ^J}5fq import AS2.events.Event;O&}c-LA!eU
import className;
AX5yQxQ ...
'X Nr9u9ZHV@ var cn:className = new className();x7I!H1A&^1X+Vfm
//事件同名函数.
xEPS tA7\ZH h function complete(evt:Event):Void
;Wm SAD8tr3W3Y { t7b"@'O FC ZlD I
    trace(this); //输出: this(指向侦听器对象)
e&]2l ^8p^v4q.E }
o/]Gm1h1c cn.addEventListener(Event.COMPLETE, this);2N2}r[!S
...2Y\Amy
移除侦听:
LpR'b u%R //使用自定义函数.c g!g!sf%|*Z
...|@k$z+P6o
cn.removeEventListener(Event.COMPLETE, completeHandler);e,H2j/s0IZ#FAt
...x1VJ'T{/s
8iOf c Q{1u y[N q
//使用事件侦听器对象.
Z;?3Yk qRoGQ ...^MrMP)`
cn.removeEventListener(Event.COMPLETE, this);K1{o [B:t6D
...
c})?&K4Fdu AS2.utils.CFDelegate;
m!o*`s1@sR AS2.events.Event;/SK ^{:ZX"w1a*bm&D(sM
AS2.events.CFEventDispatcher;:EQ1OF3iJrf}])}
这些是什么?下面讲解:
o@F t[]DM_VV1V [6.1.创建 CFDelegate 类(修改 Delegate 类)]8_D]L_}/v[
CFDelegate 类是 Delegate 类的修改版本.简化了代码(一般不用的功能).提高了执行效率.
!DC~yG.FivXI 此类文档详细:
Gm C!sY+`Mk"h/y C8l Classes/AS2/utils/CFDelegate.as
^NU:wrZ3xs'U+O 主类:2Q6E)?S Nhk |5r
打开 CFDelegate.as 文档.输入下面的代码:$t O4xC9z5H,u K$q%h
class AS2.utils.CFDelegate
D0V[/Z c&{ {
Y#SnS*b\l     public static function create(scope:Object, method:Function):Function
f7iBi$N@C+k m\     {(Y{4xa*KSM
        var f:Function = function ()
C?m6P7lw;p*P#f         {
3G6RM x#s.W8la             method.apply(scope, arguments);T{!h/el-| b'v
        };+S U [2Kr
        return f;
8giedP)W%@fl     }$FW6a*uR ?zF
}hB1i NS8nq [ G ft
保存文档.
8zn g)e6v i[[w%Hj [6.2.创建 CFEventDispatcher 类(修改 EventDispatcher 类)]n!y*X;z!gncv
CFEventDispatcher 类是 EventDispatcher 类的修改版本.简化了代码(一般不用的功能).提高了执行效率.)AK es*gp
此类文档详细:
(HK t7fh4\ W Classes/AS2/events/CFEventDispatcher.as
tF.N]8sO7{h9| 主类:
[g]j0GSF odSu 打开 CFEventDispatcher.as 文档.输入下面的代码:0C$VZ7RU4?
*/ oHB c|F[
//----------------------------------------0[S8B bj
class AS2.events.CFEventDispatcher
_Z pP f g?'] {DfDJ2~9l
    //----------------------------------------
)Yr7kq-Q1t&\w;H     //构造函数
b!h m{nH.mD     public function CFEventDispatcher(){}L\ M#Y OX@
    //---------------------------------------- RU NS W.J
    //当不继承此类时,此属性才有效.D2q N+Hh!o
    private static var _ed:CFEventDispatcher;
+_+R2p|!d)_7B     //----------------------------------------c!Vj%{|7a5Y
    private static function _removeEventListener(queue:Object, handler):Void3g'\s h6]1}3N
    {-p ox zqm)qJ s
        /*ME9`)yTI"c~&n9a
        这里主要用于删除事件数组中的事件处理器.3E lC!R[%qt
        */i/B8[ ui\
        if (queue != undefined) {
*w1u/~Fn%e'Zmig(]             var l:Number = queue.length;
3o*i/p,SK             while(l--){BE QZS,o NZ"D2v"V
                if(queue[l] == handler){3t-]L*S Ztf
                    queue.splice(l, 1);YPd:un} @
                    return;
KNf8Eb5ocy                 }0{A)a*e5QHj^
            }
O)rM^2PNO}*j         }
\%qq7Hm'F6[:K4O     }3B|K,q\(o
    //当不继承此类时.此方法有效./` C4w d9xG:TL
    public static function initialize(o:Object):Void
g ?[U)vv6\r}7TW     {2f?b r@
        /*
)o5N6DR*Fe9v1p         如果没有继承此类,而是使用 initialize 此方法时, _ed 等于 undefined.然后创建此类的实例.
5|1[mNWG\*T4lo&n         最后将事件通知和侦听器管理功能添加到 initialize 方法中的对象 o.} P%^4B:L^Y D
        前面所讲的不继承此类时需添加的三个方法,其实是四个.还有 dispatchQueue 方法.但此方法在N*x7Qz oEpO
        调用 dispatchEvent 方法时就会自动调用.可能有人会问,为什么没有定义就能调用?因为在函数
&SQ7d|[j h         中可以操作对象.从而对对象动态添加方法和属性.这里就是用了在函数中操作对象.
T z oy%T-CG         */#^~}QVNT:W
        if (_ed == undefined) { d'pl+b4?5mif,@A(f
            _ed = new CFEventDispatcher();
2w/G,qU&@.wk,Cj         }
!] S$v+B%N0jNv         o.addEventListener = _ed.addEventListener;?(M D3Z$X9o
        o.removeEventListener = _ed.removeEventListener;
$s4@\4x,MS         o.dispatchEvent = _ed.dispatchEvent;on&y-JA|#N
        o.dispatchQueue = _ed.dispatchQueue;a[/xm]
    }
H'eta8~{JOM     //----------------------------------------
HS:j&hJ     private function dispatchQueue(queueObj:Object, eventObj:Object):Voidx0~E4bh5G
    {
+mr3g%c)k*Xl;z-O         /*
#L sW(V5K          这里主要用于判断事件处理器是对象还是函数.Z5r'OfA NT5L
        */^)ln Yth)G
        if (queueObj[eventObj.type] != undefined) {%s&`^%Tq:Y
            for (var i:String in queueObj[eventObj.type]) {
(_gH N G-gX-l                 var o = queueObj[eventObj.type][i];
HEL5l&b+Y                 if (typeof (o) == "object" || typeof (o) == "movieclip") {-B\ ZG0aS7Ck*D
                    //调用对象中的handleEvent函数.mfs/IL_&b
                    //if (o.handleEvent != undefined) {*z9\\(W&rl b/w
                        //o.handleEvent(eventObj);5we7i{B_;K
                    //} _/G+[\z|V6d
                    //调用对象中的事件同名函数.  .z7{#W:N;Eu9Ck_
                    //if (o[eventObj.type] != undefined) {A1m-C&w#D@ z0\{S
                        o[eventObj.type](eventObj); d#`rB jA&f*m} ug
                    //}.poC#a)zN e`d
                } else {
h {r AR/r                     //调用自定义函数.
H!u)u yV'U                     o.apply(queueObj, [eventObj]);
;QKM8fsO%GY                 }
/An*y#Q2mLS,G;I             }gaq t;n)pB8?j
        }
9M9JA\-gV)Zm5L     }
@ Y;^f4SJn7g     public function dispatchEvent(eventObj:Object):Void,zO1M!B&v,Qbe,|ge
    {gD v_9^Gm
        //将事件源始终指向this(应用此类的对象).[6e J C#gzZ:c%e {
        eventObj.target = this;;D;igk9a b
        //此句对动态类,或在类中定义"事件名Handler" 这样的函数时才有效.在这里我注释了这句.你如果你想用,可以启用它._XQ"Z0KtQ W
        /*Lk kY8Y
        用法: 对象.事件名Handler = function(evt:Object){};&cb;J%sh2_
        */6FQ L2L&m$a
        //this[eventObj.type + "Handler"](eventObj);p,P2V5hp#J
        this.dispatchQueue(this, eventObj);Q+PhG"~ Z5K
    }
f|5j+\8l4AC:nc1y     public function addEventListener(event:String, handler):Void
!MBrMb[Q     {/d7{A1^W|0[.F
        //这里可以这样理解:
;b0vWB9e&K         /*O8o |k7I
        使用 Y5g1Y g"K [*d*D.}Ti*a0P
        addEventListener("click", 事件处理器);*C?shl
        添加事件.G s5L9z'iz
        这时, this["click"] 就等于 undefined.ju)X0{D @l
        (this["click"] == undefined) = true y9Z_:I cdJ
            然后将创建一个新数组来存储事件处理器.
(g8VE3ul-Q             this["click"] = [];$M MK0x k:_#~E3M.`
        然后执行
X)l|t:l.q2h         CFEventDispatcher._removeEventListener(this["click"], 事件处理器);7BwYF.AS/{
        来检测此事件是否有相同的事件处理器.如果是就删除它.]tu"V5}0a
        举个例:当你在一个网站注册用户名时.网站的注册程序会从数据库中检测是否有与你相同的用户名.8ts/C/xEeS
        如果有将会提示你重新输入用户名(在这里就是直接删除了).如果没有就会注册成功(这里就在后面M+f7H*l)rS'`
        执行 push).但是网站的注册程序不会从数据库中检测是否有与你相同的密码.
&_@J)x J[O0N:\*R` V         
]!S[F/S_#hn@         就是说一个事件,可添加多个不同的事件处理器,但不能添加相同的事件处理器.
Ck%FQ&j)h)^_bo         当添加新的事件时,也是一样的2i4SL h2G9T"_nTV6|
        
)b"F5C@0o5v$JD"O3n         最后使用!s\.xb/^B
        this["click"].push(事件处理器);
V8Kh%ytO         将事件处理器添加到事件数组.
;^H}sx         */
rW+rC,~"G'Fs         if (this[event] == undefined) {a0FECYy!mP,HB
            this[event] = new Array();
:bggs$Cq         }
"mO;\ho(W D]         //ASSetPropFlags 是隐藏的方法.用它和不用它貌似没有区别.大家可以研究下.1IF)[D]:O,x5q&Bu
        //_global.ASSetPropFlags(this, event, 1); OQ8t J)E7O
        CFEventDispatcher._removeEventListener(this[event], handler);
Vo r` PQ)|S@.{,k         this[event].push(handler);
vl(O"HH$XL+PT     }
O8GV2v/D.ND*q5X     public function removeEventListener(event:String, handler):Void
~4l'cxQ&W0F-s D     {
bbKZJn+P%wP         //这里我就不啰嗦了.}%a_2cqA
        CFEventDispatcher._removeEventListener(this[event], handler);
+n6[T@-t;{z     }
p,yai&r*o5hik     //----------------------------------------
6fA%u1uQ%f[#` }7E"^,L,laoQ
保存文档.
"Q"a,K&R T/r*M [6.3.创建 Event 类(事件基类,继承 Object 类)]
2R]c {K 你可以把它看作事件对象.因应它的工作就是生成事件对象.*k S]$su1C*T
此类文档详细:
Gu Y$M*Av2r Classes/AS2/events/Event.as
.H_/jt \ 主类:0hl+h a]2o#F q)t
打开 Event.as 文档.输入下面的代码: c9}| dlA)Qt)I
class AS2.events.Event extends ObjectlOb2Dzve j?
{%k:l6@B ~'?$wzmL,T
    //----------------------------------------$^qz0[qA0c&uid
    //事件的常数名.bQ0izo
    public static var COMPLETE:String = "complete";e*s5As8^ud
    public static var CANCEL:String = "cancel"; o VPn-|Z2D#t6K ?D
    public static var CHANGE:String = "change";
&c[T!v\K;TX     public static var CLOSE:String = "close";s-n;J Kf2SJ
    public static var CONNECT:String = "connect";
P f `Q Xa%c     public static var FULLSCREEN:String = "fullScreen";w7hES"f|9{D
    public static var OPEN:String = "open";
uDcy.b$fV6e     public static var REMOVED:String = "removed";b3X }6d:Z O
    public static var RESIZE:String = "resize";#x4}(O*R;^8H3i Vl
    public static var SCROLL:String = "scroll";
P U h+lliK     public static var SELECT:String = "select"; f ze^!C``M3L
    //----------------------------------------
;f*n}:Y oI l     public var type:String;
Y7n+|G4~m%z.g     public var target:Object;^4JG*F${7A
    //----------------------------------------
k/h'X$w!?     private var className:String = "Event"; d t*M5FAN'R
    //----------------------------------------
%F@#hA%{9n B     //构造函数.
h c7f!QMm%QSWF#G     public function Event(type:String)^\ T.~"e#Qr
    {^&oTQPOG8]#e
        this.type = type;
1d;b j(zZj5ny     }8@H)Rj*\dDU4I
    //----------------------------------------W[Gx?Qy]"T
    public function toString():String
;A2mm"T;K:~     {
i1e@ w@:j1Z'v9N4A         var str:String = "";B&N6o3}5IE?*r)}
        for (var i:String in this) {A"x,DLV5m
            if (this[i] != undefined) {
$DueE5T@0G                 str += i + "=" + this[i] + " ";ji#SZp
            }v uOY.xx
        }
\9CF.U6]ZJ)m         return "[" + this.className + " " + str.slice(0,str.length - 1) + "]";
#}y-}|#N     }
4e;ZC-Af*W0s)C/r;y)j2x     //----------------------------------------
!^"z'?{zbr@ }
9Ac|Uj B.v upO _ 保存文档.
lUE'N\sHT 此类包含下面内容:EJ8Fd-?
1.事件的常数名.如:a{gC(tD do
    public static var COMPLETE:String = "complete";
7w+vPw On `O.Ab$f,D     ...
NyP+S,[-D Q2I5~b 2.基本的属性.如:9z3}$pP!CS
    public var type:String;
9@1rc#z-yu     ...4Ej2Xi t+bYh t
3.className 属性.如:
`{ez,eFK private var className:String = "Event";? iL-Tc!}
4.构造函数.如:
5i%~^}.N`2gt     public function Event(type:String)dFA1z4wU^X8P+q
    {Q$MRz;OlW-C
        this.type = type;;v;x)v#V"rNn!c.{5V
    }
}a+o*L1u$Y2n;r 5.toString() 方法.如:
K5vc9jb     public function toString():String$[!uj&U @#t
    {
AE/Hm;p [u7s m         var str:String = ""; T fZ^dp
        for (var i:String in this) {;oh:dc g6P)K:wfc
            if (this[i] != undefined) {KZ4R0{/P
                str += i + "=" + this[i] + " ";d yjQeNr}iw
            }
K(S6['^$U(l-[f8C         }v _8n F7A
        return "[" + this.className + " " + str.slice(0,str.length - 1) + "]";T:M f'H.~B zO
    }
P2]8w[5\il6R6`+m %{g/sx:@}0O1\d*GZ*L
如果你嫌此方法阻碍你的执行效率.可以改成如下(标准):
/G4hT LO#b2r     public function toString():String8?'V] fS)i4C1I!?5z
    {4f2N;o\Z+o Nz(U
        return "[object " + this.className + "]";%^Z!_Ai+sX
    }] c6tb!@
这里讲下 toString() 方法.在类中定义此方法.在输出此类实例名实调用此方法.如:
No!JY(F-t class className
l3XF~dR$Ff {
7j+l/k%Y1}(m/N     ...
%a`O T2{\/R6Zs     private var className:String  = "className";.bm(W;D:eo:b$W
    public function toString():StringKV"Vlz!@"P
    {
x qE4N;w$N`a         return "[object " + this.className + "]";+~VzAxVj0~SA
    }*? [e(rR$~'g0y {)Y+`
    ...S0_xG1Yd,[Hl
}
p([(B GwX"Wh1Q
3\Vu4PN O5l#g(tQ import className;[z}w&[
var cn:className = new className();"{WkE/R
trace(cn);// 调用 toString() 方法.输出: [object className]
'LnRCoJ 当然你也可以改成 AS3 中 Event 类一样的方法.但没有必要,很少会用到.
q)o+V*h9O)T+O:@ ~ 如果要向 Event 类传递参数和定义新的事件名,请看下面.
FqI+v9E'L.Na1g [6.4.创建 IOErrorEvent 类(错误事件类,继承 Event 类)]!E)b0qY3vW I5uG7z
此类文档详细::tZ5K6J}P
Classes/AS2/events/IOErrorEvent.asdK8I*r I
主类:
'PW)v;F\c.Ox8H)s p 打开 IOErrorEvent.as 文档,输入下面的代码:o&|5B7Qm.` k^Y'T4t
import AS2.events.Event;
;T_o N1st0J,U //----------------------------------------h ^*\5l9g2|O#J%K5}
class AS2.events.IOErrorEvent extends Event
4HH E)H~j1h2c {
&JGq$E*gi;X     //----------------------------------------
&|/W0iSG2v2H q     //事件的常数名.uU"ro2Ja3p }4u2O,B
    public static var IO_ERROR:String = "IOError";1YMX \.T
    //----------------------------------------
c-r X;eZq|-Z Z     //属性参数.
Qu-X!]O-?$NN6M     public var text:String;
1L(Y m j2c8?U     //----------------------------------------2PN*M%`7G0l5d!f4t kc
    //className 属性-l%l X,kTT
    private var className:String = "IOErrorEvent";