为何采用这种方法
一个状态的改变牵扯多个对象,比如玩家获取了一件物品.此时可以解锁某个关卡,也还使得玩家战力提升,还使得玩家可以拥有更多的背包格子.
好像可以用事件的处理机制来处理这种事情,当玩家获取物品时,派发事件,在多个事件里面监听.
但是这种有个弊端,并不是同步,且针对性不强,且无法及时去除事件的监听.
实例分析:红点状态改变
很多游戏控件上,如果有新内容需要显示红点,点击后红点消失.好像十分简单,但是随着项目不断变得复杂,红点牵扯到的东西越来越多.比如有个宝箱上的红点显示条件为:玩家为vip且等级为4,玩家没有加入家族,玩家人物等级大于30.当宝箱被点击,红点消失时,关于红点要发生下面事件:1.告诉服务器,玩家这个红点过了.2.玩家获得一个免费领取的奖品.
RedPointManager
红点管理器
以下四个属性
//caller对象的词典
private _callerOfHashCode: {
[hashCode: string]: any }
//回调词典
private _callbackOfHashCode: {
[hashCode: string]: {
callback: (haveUnread: boolean) => void, caller: any } };
//对象所注册的keys
private _keysOfhashCode: {
[hashCode: string]: string[] };
//某个key对应被注册的对象
private _hashCodesOfKey: {
[key: string]: string[] };
//键值对
private _valueOfKey: {
[key: string]: boolean };
对这四个属性的操作将实现这个功能.当我们要开始将一个函数关联到红点的时候,将会把函数所在对象储存进 _callerOfHashCode,hashCode做为键值对中的键是对象名,将函数储存到 _callbackOfHashCode .
一个函数有可能关联多个红点 ,_keysOfhashCode正是用来记录这个,键用的就是 hashCode 值用的就是红点名,我们事先将红点定义相关名字,比如
class UnreadDefine {
/**
* 背包上红点
*/
static EDS_RANK_BE_REPLACED:string = "EDS_RANK_BE_REPLACED";
/**
* 宝箱上红点
*/
static TOP_BATTLE_IN_TIME:string = "TOP_BATTLE_IN_TIME";
public constructor() {
}
}
"key"这个键是字符串类型,正是红点名.当一个红点发生改变,需要通过红点名获取所有的 hashCode 再通过 hashCode 获取对应的函数并执行.那么 _hashCodesOfKey 就是红点名对应的所有 hashCode.
最后一个属性 _valueOfKey 是储存红点的状态,true 则显示红点, false 不显示.
以下展示整个对象的逻辑.
class UnreadManager {
//caller对象的词典
private _callerOfHashCode: {
[hashCode: string]: any }
//回调词典
private _callbackOfHashCode: {
[hashCode: string]: {
callback: (haveUnread: boolean) => void, caller: any } };
//对象所注册的keys
private _keysOfhashCode: