分享
 
 
 

FlashMX2004的事件机制

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

前言:论坛里关于AsBroadcaster(广播)类的讨论很多,有很多精妙的讲述,但为了和EventDispatcher(派遣)类有个比较,不得不把这位"老兄"拉来客串一下。对它我不会讲的很详细,不解的地方可以去搜搜前辈的帖子哦。

AsBroadcaster(广播)类在MX(flash6)里写做"ASBroadcaster",这是为什么有时会发生以前的程序在2004版里发生异常的原因之一。AsBroadcaster 类具有四个静态的方法:

------------------------------------------------------------------------------

static function initialize(o:Object);

//o:对象

//initialize:初始化方法,为对象o附加上作为事件源的各项功能。那么事件源都有什么功能呢?

static function broadcastMessage(msg:String);

//msg:消息

//broadcastMessage:广播方法,事件源的一个主要功能就是向外界广播一条消息,告知听广播的人"某一事件发生啦!"

static function addListener(o:Object);

//o:对象

//addListener:注册监听者方法,也就是决定广播消息给谁听的意思

static function removeListener(o:Object);

//o:对象

//removeListener:注销监听者方法,也就是消息不再广播给谁听

--------------------------------------------------------------------------------

如此看来AsBroadcaster类也不怎么复杂嘛,下面看看它的具体使用吧!

-----AsBroadcaster测试.fla 开始------

var 司令部=new Object();

//啊,司令部是个发布指挥消息的地方,用它做事件源是个不错的选择

AsBroadcaster.initialize(司令部);

//这里直接用AsBroadcaster来引用AsBroadcaster类,原因如上述

//调用AsBroadcaster类的静态方法initialize,为司令部附加上作为事件源的各项功能

var 步兵=new Object();

//生成步兵对象

步兵.on进攻=function(){

//on进攻: 这里之所以用’on’做前缀,是为了表明这个方法是响应一定事件的方法

trace("步兵接到司令部来电,轻装上阵,火速向敌方阵地前进!");

// 接到’on进攻’消息后采取的措施

}

步兵.on驻守=function(){

//同上

trace("步兵接到司令部来电,就地待命,多设岗哨,严防来犯之敌!");

}

司令部.addListener(步兵);

//将步兵添加为司令部的监听者,从现在起他将听从司令部的指令行事

//以下雷同的地方,恕不赘述

var 装甲兵=new Object();

装甲兵.on进攻=function(){

trace("装甲兵接到司令部来电,加足马力,火速向敌方阵地开进!");

}

装甲兵.on驻守=function(){

trace("装甲兵接到司令部来电,就地待命,检修装甲,作好随时进攻的准备!");

}

司令部.addListener(装甲兵);

var 炮兵=new Object();

炮兵.on进攻=function(){

trace("炮兵接到司令部来电,向敌方阵地猛烈轰击!");

}

炮兵.on驻守=function(){

trace("炮兵接到司令部来电,就地待命,保证弹药准备充足!");

}

司令部.addListener(炮兵);

//-------------------下面开始演示------------------------------------

trace("司令部一号指示");

司令部.broadcastMessage("on进攻");

//司令部用’broadcastMessage’ 方法广播’on进攻’指令

trace("司令部二号指示");

司令部.removeListener(步兵);

//"将在外,君令有所不授",司令部用’removeListener’方法注销了’步兵’听从指令的义务

司令部.broadcastMessage("on驻守");

//司令部用’broadcastMessage’ 方法广播’on驻守’指令。注意:步兵现在不会驻守哦

-----AsBroadcaster测试.fla 结束-----

具体的测试结果,大家试试便知。现在我们看看AsBroadcaster类的局限所在:

1、如果司令部发出的指令是"向一号高地进攻",这个消息应该怎么广播呢?我们当然可以为步兵定义一个'on向一号高地进攻'的方法,然后监听司令部广播的'on向一号高地进攻'的消息。可是如果需要发出N个'向某高地进攻'的指令,岂不是要定义N个类似的事件方法?如果进攻的目标是随即确定的,那又该怎么去写?如果步兵同时监听"战地指挥部"的广播,他怎样根据不同的指挥者采取不同的措施?步兵并不能确定一个'on进攻'消息是来自司令部还是'战地指挥部'呀。所以说,AsBroadcaster类的第一个局限就是它虽然广播了一个'消息',却不能给出消息的具体说明。

2、我们知道战争时期为了做到策略的"因时因地制宜",常常会设一个"战地指挥部"。假设我们希望把步兵的进攻的指挥权交给"战地指挥部",而把步兵的驻守权交给"司令部"。因为司令部同时拥有装甲兵和炮兵的进攻与驻守的指挥权,所以它可以广播"on进攻"消息,但一件意想不到事将会发生:步兵也跟着进攻了!

为了防止出现差错,司令部就不得不在进攻前"removeListener(步兵)"。但为了防止广播 "on驻守"消息时步兵不再驻守,所以在广播完"on进攻"消息后必须再次"addListener(步兵)"。司令部何其累哉!所以说,AsBroadcaster类的第二个局限就是它注册了一个监听者,却并不关心监听者到底是监听它的什么事件。

3、AsBroadcaster类的第三个局限其实是由第二个局限来的,就是它有些情况下会造成运行的低效。假设还有一支空军, 它有"on空袭"事件方法,并且归司令部指挥。当司令部广播"on空袭"消息时,得,步兵、装甲兵和炮兵就会也试图执行"on空袭"事件方法,当然是浪费时间啦.

说了AsBroadcaster类这么多局限的地方,并不是说AsBroadcaster类不好,而是说要根据情况选择使用不同的事件机制。如果不涉及到上面说的几种情况,用AsBroadcaster类其实很方便的(比EventDispatcher类要省事)。也正因为AsBroadcaster类有这么多局限的地方,才使我们的主角EventDispatcher类登上了光辉的舞台,请看我们下篇的讲述吧!

------------------------------------------------------------------------

补充1:

AsBroadcaster.initialize(o)方法会为o创建一个"_listener"数组,它用来存储所有的监听者对象。

补充2:

FlashMX 2004里还有个mx.transitions.BroadcasterMX类,它比AsBroadcaster的功能要强大,支持广播消息时附带更多的参数,可以对消息进行更多描述

在上篇中我们提到了AsBroadcaster类包装的广播器作为事件源的诸多限制,现在就看看EventDispatcher(派遣)类是如何拓展事件源的功能吧。

EventDispatcher类有2个静态方法:

----------------------------------------------

static function initialize(object:Object):Void

//object:对象

//initialize:初始化方法,为对象object附加上作为事件源(在这里可以理解为派遣中心吧)的各项功能。

static function _removeEventListener(queue:Object, event:String, handler):Void

//一个内部方法,注销监听事件源相关事件的监听者,removeEventListener方法会调用它.

-------------------------------------------------

EventDispatcher类有4个公共方法:

function dispatchEvent(eventObj:Object):Void

/*事件派遣方法,向外界广播一个消息,并附有关于消息的相关描述(请与broadcastMessage(msg:String)方法比较)

eventObj:事件对象,它至少应含有2个属性,假设司令部为一个事件派遣中心,一般定义如下:

var eventObj=new Object();

eventObj.target=司令部;//定义广播消息的对象

eventObj.type="on进攻";//定义消息的具体类型

其中target属性也可以不定义,dispatchEvent方法会将它设为默认的广播消息的对象。

*/

function dispatchQueue(queueObj:Object, eventObj:Object):Void

/*这个方法的中文意思,我根据它的功能将它称为"事件传达"。

queueObj:一个事件派遣中心对象

eventObj:事件对象,注意:与 dispatchEvent不同,它的target并无默认值,需要你手工设定.

为什么将这个方法称为事件传达呢?因为它可以让当前的事件派遣中心指示另一个事件派遣中心(方法的第一个参数)向外界广播消息。其实在dispatchEvent方法的内部就调用了dispatchQueue,只是将参数queueObj设为当前的事件派遣中心罢了。

*/

function addEventListener(event:String, handler):Void

/*注册某个事件的监听者

event:监听的事件名称

handler:监听事件的对象

这个方法与AsBroadcaster类的addListener方法相比,多出了参数event,

明确了所监听的具体事件。

*/

function removeEventListener(event:String, handler)

/*注销某个事件的监听者

event:事件名称

handler:要注销的监听事件的对象

这个方法与AsBroadcaster类的removeListener方法相比,多出了参数event,明确了从哪个事件中注销监听对象。

下面就让我们在战场上实战一下EventDispatcher吧。假设有两个指挥中心,一个是司令部,一个是战地指挥部。有三个兵种,分别是炮兵、步兵和敢死队。司令部可以指挥炮兵的进攻、驻守和步兵的驻守,战地指挥部可以指挥步兵的进攻、冲锋和敢死队的冲锋,并且司令部可以向战地指挥部传达指示。下面是实现上述复杂关系的代码:

-----EventDispatcher测试.fla 开始-----

import mx.events.EventDispatcher;

//导入 mx.events.EventDispatcher类

var 司令部 = new Object();

司令部.名称 = "司令部";

EventDispatcher.initialize(司令部);

//为司令部对象附加上派遣中心的相关功能。

var 战地指挥部 = new Object();

战地指挥部.名称="战地指挥部";

EventDispatcher.initialize(战地指挥部);

//为战地指挥部对象附加上派遣中心的相关功能。

var 步兵 = new Object();

步兵.on进攻 = function(eventObj) {

//步兵的’on进攻’事件处理方法,记住需要有参数

var 来自=eventObj.target.名称;

//eventObj.target引用广播’on进攻’事件的对象,用它可以访问事件源并反馈消息。

var 阵地=eventObj.阵地;

//获取事件的关于’ 阵地’属性值

trace("步兵接到"+来自+"来电,轻装上阵,火速向敌方"+阵地+"前进!");

};

步兵.on驻守 = function(eventObj) {

var 来自=eventObj.target.名称;

trace("步兵接到"+来自+"来电,就地待命,多设岗哨,严防来犯之敌!");

};

步兵.on冲锋=function(eventObj){

var 来自=eventObj.target.名称;

var 阵地=eventObj.阵地;

trace("步兵接到"+来自+"来电,向敌方"+阵地+"发起冲锋!");

}

司令部.addEventListener("on驻守", 步兵);

//向司令部的’on驻守’事件注册监听对象’步兵’

战地指挥部.addEventListener("on进攻", 步兵);

//向司令部的’on进攻’事件注册监听对象’步兵’

战地指挥部.addEventListener("on冲锋",步兵);

//向战地指挥部的’on冲锋’事件注册监听对象’步兵’

var 炮兵 = new Object();

炮兵.on进攻 = function(eventObj) {

var 来自=eventObj.target.名称;

var 阵地=eventObj.阵地;

trace("炮兵接到"+来自+"来电,向敌方"+阵地+"阵地猛烈轰击!");

};

炮兵.on驻守 = function(eventObj) {

var 来自=eventObj.target.名称;

trace("炮兵接到"+来自+"来电,就地待命,保证弹药准备充足!");

};

司令部.addEventListener("on驻守", 炮兵);

司令部.addEventListener("on进攻", 炮兵);

var 敢死队=new Object();

敢死队.on冲锋=function(eventObj){

var 来自=eventObj.target.名称;

var 阵地=eventObj.阵地;

trace("敢死队接到"+来自+"来电,向敌方"+阵地+"发起冲锋!拼死也要拿下!");

}

战地指挥部.addEventListener("on冲锋",敢死队);

//---------------------------------------------------------------------

trace("司令部指示:");

var eventObj1 = new Object();

//定义事件对象eventObj1

eventObj1.target = 司令部;

//定义事件对象eventObj1的target属性值为司令部

eventObj1.type = "on进攻";

//定义事件对象的事件类型为’on进攻’

eventObj1.阵地="505阵地"

//一个自定义的属性’阵地’,你可以附加更多其他的属性

司令部.dispatchEvent(eventObj1);

//司令部将定义好的事件对象广播出去,只有向它注册了’on进攻’属性的监听对象才能收到。步兵并不会发动进攻。

trace("战地指挥部指示:");

var eventObj2=new Object();

//eventObj2.target=战地指挥部;

//因为dispatchEvent方法会自动将事件对象的target属性设为默认的广播消息的对象,所以这句也可以注释掉。

eventObj2.type = "on进攻";

eventObj2.阵地="105阵地"

战地指挥部.dispatchEvent(eventObj2);

trace("传达司令部指示:");

var eventObj3=new Object();

eventObj3.target=战地指挥部;

//这里必须设定事件对象的target属性。因为dispatchQueue不会为target属性设定默认值

eventObj3.type="on冲锋";

eventObj3.阵地="123阵地";

司令部.dispatchQueue(战地指挥部,eventObj3);

//战争时期也许司令部并不知道前线部队的布置情况,所以它可以将指令传达给战地指挥部,由战地指挥部将事件对象广播给向自己的相关事件注册的监听对象

-----EventDispatcher测试.fla 结束-----

具体的测试结果我就不贴出来了。最后说说EventDispatcher类的几个有趣的地方:

1、监听事件的对象可以是Object、MovieClip,还可以是Function.例如:

假设在战场上每当发起冲锋时,都要呐喊助威,可以这样写:

function 鼓励士气(){

trace("冲啊!杀啊!");

}

战地指挥部.addEventListener("on冲锋",鼓励士气);

2、当监听事件的对象是自身时,一般的写法是这样的:

战地指挥部.on冲锋=function(){

trace("同志们,我们一定会取得最后的胜利!");

}

战地指挥部.addEventListener("on冲锋",战地指挥部);

但是还有一种更简洁的写法:

战地指挥部.on冲锋Handler=function(){

trace("同志们,我们一定会取得最后的胜利!");

}

这种写法不再需要用"addEventListener"来注册了。它有两点需要注意,一是它总在其他监听对象的事件处理之前执行,再就是它无法用'removeEventListener'方法注销监听。

3、监听对象的事件处理程序也可以这样写:

步兵.handlerEvent=function(eventObj){

var 来自=eventObj.target.名称;

var 阵地=eventObj.阵地;

var e=eventObj.type;

switch(e){

case "on进攻":

trace("步兵接到"+来自+"来电,轻装上阵,火速向敌方"+阵地+"前进!");

break;

case "on驻守":

trace("步兵接到"+来自+"来电,就地待命,多设岗哨,严防来犯之敌!");

break;

case "on冲锋":

trace("步兵接到"+来自+"来电,向敌方"+阵地+"发起冲锋!");

break;

default:

break;

}

司令部.addEventListener("on驻守", 步兵);

战地指挥部.addEventListener("on进攻", 步兵);

战地指挥部.addEventListener("on冲锋",步兵);

好了,关于EventDispatcher类到此就介绍完了.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有