事件机制在很多高级设计语言中都有支持譬如VB、C#(delegate)、CBuilder(并不属于C范畴CBuilder中事件处理器必须用关键字closure<闭包>修饰)等等甚至在HTML中也可以见到它身影事件机制引入使软件Software系统变得更加易于理解——它使种语言(平台)更加接近于这个世界真相事情发展变得像现实世界中那样顺理成章某事件产生引发了系列其他事件产生这些事件要么是结果要么又会引发系列事件产生……如此这般信息才得以在事件新陈代谢中延续世界才得以向前发展在某些游戏设计过程中项重要任务就是模拟现实世界某些特征以期实现机器和用户更加亲密沟通事件机制就是很好例我们需要事件来使我们系统更加人性化
我想在我继续进行下面对讨论的前先简单介绍下“事件”这个东东
1. 游戏中事件机制
联系是普遍存在事事有联系、时时有联系整个世界是个相互联系统整体个人行为、物状态改变或事进展过程某阶段可以引发个事件个事件发生或许会引发另外事件——通过人感知、大脑反映然后作出决策付诸行动——也或许就这么蒸发掉无人知晓但无论如何在这过程中我们总能抽象出些实质性东西来就像下面图示:
在游戏中:
事件源——表示任何可以引发事件对象譬如个“人”、“坦克”、“建筑物”、“地面”
事件——表示任何可以处理事件譬如“感冒”、“射击”、“倒塌”、“有对象经过”
响应者——表示任何对某事件感兴趣对象
响应器——表示对某事件感兴趣对象对某确定事件作出反应
特别,对于过程:
通知——发生在事件和响应者的间我们把它分为两种方式:有限听众式、广播式对事件感兴趣对象(响应者)只有确定有限个(只有个情况下可以叫做点对点式)情况就是有限听众式而对于广播式事件并不知道会有哪些(个)对象对自己感兴趣它向所有可以接收事件通知对象广播事件
触发——响应者发现自己对特定事件需要做出相应行动时就会触发事件处理器并同时传递需要事件信息给它对于响应者它也可以选择沉默——自己了解事件但并不作出行动因此这个过程决定权在响应者手上
2. 万事的鼻祖 Event
我们需要个类来表示所有事件普遍性质
public Event {
// 属性
public Name { get;; }// 获取或设置事件名称
public Message { get;; }// 获取或设置事件简单描述
EventTypes EventType { get;; }// 获取或设置事件类型(枚举EventTypes)
ListenerCollection Listeners { get; } // 获取响应者集合
public bool PoolEvent { get;; }// 获取或设置事件简单描述
// 思路方法
void RaiseEvent; // 通知响应者事件发生
void AbandonListener( index ); // 抛弃个事件响应者并把它从 Listeners 中移除
void AbandonListener; // 抛弃所有事件响应者
}
3. 枚举类型 EventTypes
这个枚举类型指示事件通知过程类型:有限听众式、广播式
public enum EventTypes {
LimitedListener ,
Broadcast
}
4. 响应者接口 IListener
该接口只有唯思路方法 EventArrived 事件发生时会这个思路方法并传递相关参数这个参数必须是 EventArgs 或由它派生而来
public erface IListener {
// 通知个响应者事件到达
void EventArrived( EventArgs args );
}
5. EventPool
个事件池当且仅当需要事件广播时我们才需要它需要注意是 AddEvent 思路方法它把个事件添加到池中第 2个参数指定是否将该事件已经指定响应者亦添加到广播响应者中事件添加后其 Event::EventType 属性会被设置为 EventTypes.Broadcast
public EventPool {
// 属性
public ArrayList Events { get; }// 获取池中所有事件集合
public ListnerCollection Listners { get; }// 获取池中所有响应者集合
// 思路方法
void AddEvent( Event obj bool copyListners ); // 添加个事件并把它作为广播式事件
void RemoveEventAt( index ); // 将个事件从列表中移除
void RemoveEvent( Event listener ); // 将个事件从列表中移除
void Broadcast( Event event ); // 向列表中所有响应者广播指定事件(可以是非池中事件)
void BroadcastItemAt( index ); // 向列表中所有响应者广播池中指定事件
}
6. EventArgs
public EventArgs {
public Event Event { get; } // 获取传递这个参数事件
public object Sender { get; } // 获取事件源
}
7. UML Diagram
8. 响应者行为
响应者实现 IListener 接口后就可以响应事件了在 EventArrived 思路方法中你可以直接处理事件抑或是其它事件处理器(响应器)C#中有很好解决方案——委托——替代指针最有效思路方法在C中也可以用虚拟表来模拟委托机制总的在响应器上解决方案是很灵活在实际开发中可以根据区别环境做出区别选择
9. 扩展机制
在个游戏中除了已经定义好事件外其剧情或功能可能会要求玩家自行定义些事件这就需要种可扩展方案我们引入了 CustomEvent 类——继承自 Event以及 Condition 类
public CustomEvent : Event {
public CustomEvent( Condition condition ) {
_Condition = condition;
}
=style2>public Condition TestCondition { =style2>get{ _Condition; } }
Condition _Condition = =style2>null;
}
public abstract Condition {
public Condition {}
bool abstract Test;
}
化个 CustomEvent 类时必须同时传入个 Condition 类Condition 类必须被继承Test思路方法在适当时候被以检测是否可以引发这个事件
10. 后记
以上谈到只是个简单模型是否实用还要等待实战检验欢迎读者批评和建议
最新评论