记录 碰到的两种事件监听的解决方案
先明确方案的目的:
使得类当中的函数,在事件分发的时候被调用
比如:希望当玩家死亡的时候,玩家的角色倒下
我们希望的是 当玩家死亡的时候,系统"告诉"死亡处理函数:"玩家现在死亡了,倒下了",即当玩家死亡的时候调用Player类中的onPlayerDead函数
js
/*系统提示类*/
public class Player
{
...
/*
玩家死亡的时候调用
@param data 附带的数据
*/
public function onPlayerDead(data:*):void
{
console.log("玩家死亡!死因:{1}",parseToString(data));
fall(data);//玩家的角色倒下
}
...
}
方案一:要求类实现接口
我们编写一个"关心数据"接口,并将实现这个接口的类被注册到控制中心的"关心数据的类"的集合当中。
控制中心可将事件以及附带的数据向集合中的每个类发送。
类根据收到的事件类型,以及相应的数据做相应的处理。 如图1所示,其中A和B都是"关心数据的类"。

可以在基类中添加判断,继承了该类的子类是否实现"关心数据"接口,如果事件了,则注册到控制中心中的集合当中。
注意:当对象的生命周期结束的时候应该从"关心数据"集合当中注销掉
简化代码如下:
关心数据的接口,要求类实现 对派发的事件的类型以及数据做出相应处理
js
public interface ICareAboutData
{
function updateData(type:String,param:Object):void
}
控制中心需要负责存储注册的物体,以及分发事件
js
/*控制中心*/
public class Class Control
{
//因为该集合是全局唯一的 所以使用static
private static var dic:Object = new Object();
...
/*注意 调用static方法的时候 不需要实例化类,就可以调用*/
/*注册Object*/
public static function registerObject(object:ICareAboutData):void
{
//使用自带的内部成员属性(带有$)的
dic[object["$_GID"] = object;
}
...
/*注销Object*/
public static function unregisterObject(object:ICareAboutData):void
{
delete dic[view["$_GID"]];
}
/*广播事件*/
public static function dispatch(type:*,param:Object):void
{
for(var key:* in dic)
{
var object:ICareAboutData = dic[key];
object.updateData(type,param);
}
}
}
基类,这里主要是想说明,可以通过在基类编写判断是否为"关心数据"的逻辑,来避免为每个物体(每种角色,比如:如果敌人也要求死亡就倒下,那么继承基类就好了)都单独写逻辑。
js
/*自定义的基类,生命周期根据使用的游戏引擎有区别,这里以Laya 1.x为例*/
public class BaseCharacter extends Object
{
...
protected function onAdded()
{
...
if(this is ICareAboutData)
{
Control.registerObject(this);
}
...
}
...
/*当然地,在生命周期结束的时候应该注销*/
protected function onRemoved():void
{
...
if(this is ICareAboutData)
{
Control.unregisterObject(this);
}
...
}
}
这时,可以使玩家的角色类Player 继承这个基类,并实现接口,如下所示:
适配之后的Player类:
js
/*系统提示类*/
public class Player extends BaseCharacter implements ICareAboutData
{
...
//玩家死亡的时候调用
//@param data 附带的数据
public function onPlayerDead(data:*):void
{
console.log("玩家死亡!死因:{1}",parseToString(data));
fall(data);//玩家的角色倒下
}
...
/*为到来的事件以及数据做处理*/
/*不同的事件类型 以及不同的数据 可以做不同的处理的 也可以不做处理*/
public function updateData(type:String,param:Object = null):void
{
swich(type)
{
case EventType.PLAYERED:
onPlayerDead(param);
break;
case EventType.SOMEEVENT:;
break;//不做处理,当然不写也行,这里是为了表现差异化
defalut:
break;
}
}
}
这时候 可以假设,有以下通信协议类,收到服务器的信息之后可以发事件,通报玩家死亡:
js
public class PlayerCtr
{
public function onReceive(playerData:*):void
{
if(playerData.hp <= 0 )
{
Control.dispatchAll(EventType.PLAYERED);
}
}
}