我们在游戏开发中,消息事件的分法及响应应用的十分广泛,甚至有时候用得有些泛滥导致架构的失控以及理解代码的难度有所上升、查bug难以定位等问题。所以,有个统一的事件管理类,对游戏中所有的事件进行管理和统一的调用是很有必要的。
事件类EventManager
public class EventManager
{
public delegate void Arg0EventHandler();
public delegate void Arg1EventHandler(object arg1);
public delegate void Arg2EventHandler(object arg1, object arg2);
public delegate void Arg3EventHandler(object arg1, object arg2, object arg3);
public delegate void Arg4EventHandler(object arg1, object arg2, object arg3, object arg4);
public delegate void ArgsEventHandler(params object[] paramList);
public static class EventExtensions
{
public static void Fire(this EventManager.Arg0EventHandler eventHandler)
{
if (eventHandler != null)
{
eventHandler();
}
}
public static void Fire(this EventManager.Arg1EventHandler eventHandler, object obj)
{
if (eventHandler != null)
{
eventHandler(obj);
}
}
public static void Fire(this EventManager.Arg2EventHandler eventHandler, object obj1, object obj2)
{
if (eventHandler != null)
{
eventHandler(obj1, obj2);
}
}
public static void Fire(this EventManager.Arg3EventHandler eventHandler, object obj1, object obj2, object obj3)
{
if (eventHandler != null)
{
eventHandler(obj1, obj2, obj3);
}
}
public static void Fire(this EventManager.Arg4EventHandler eventHandler,object obj1, object obj2, object obj3, object obj4)
{
if (eventHandler != null)
{
eventHandler(obj1, obj2, obj3, obj4);
}
}
public static void Fire(this EventManager.ArgsEventHandler eventHandler, params object[] objs)
{
if (eventHandler != null)
{
eventHandler(objs);
}
}
}
注意,事件的参数最好控制在4个以内,再多的话还是建议用params object[] objs
事件声明
事件的声明可以有两种方式
第一种:直接声明
public Arg0EventHandler TestEvt0;
第二种:根据类划分事件模块
#region Test Events
public class TestEvent
{
public Arg0EventHandler TestEvt0;
}
private readonly EventManager.TestEvent testEvents = new TestEvent();
public TestEvent TestEvents
{
get { return testEvents; }
}
#endregion
事件注册/销毁
在初始化时注册,比如Start()
Game.Instance.EventMgr.TestEvt0 += OnTestEvt;
在销毁时反注册,比如OnDestroy()
Game.Instance.EventMgr.TestEvt0 -= OnTestEvt;
注意:这里的EventMgr是游戏全局管理单例类Game的一个引用,如果你不用这种方式,也可以把EventManager设置成单例类,然后EventManager.Instance.TestEvt0这样调用都行。
事件触发
在以上代码可以看到,EventManager使用了静态的扩展类EventExtensions,所以我们的事件触发调用很简单:
Game.Instance.EventMgr.TestEvt0.Fire();
或
Game.Instance.EventMgr.TestEvent.TestEvt0.Fire();
带参数
Game.Instance.EventMgr.TestEvt1.Fire(123);
Game.Instance.EventMgr.TestEvent.TestEvt2.Fire(123,"123");
只要注册了对应的事件,即可接受到触发的事件,然后把装箱参数object,拆箱强转一下即可使用,如:
void OnTestEvt(object obj1, object obj2)
{
int num = (int)obj1;
string str = obj2.ToString();
//TODO...
}
是不是很简单实用?喜欢就点个赞吧~谢谢!
Ricky Yang个人原创,版权所有,转载注明,谢谢。