使用class作为事件标识符

时间:2014-10-24 08:41:42

标签: c# class enums identifier state-machine

我正在为视频游戏中的游戏对象开发状态机实现。我希望这台状态机易于使用;为了调用状态的变化a'提升'应该在状态机上调用方法。我目前的设计涉及使用泛型类型作为事件标识符:

stateMachine.Raise<Event>();

定义:

public void Raise<EventType>() where EventType : Event

状态机然后找到处理此事件类型的状态,并根据它们提供的转换更新状态。我认为最初使用字符串来识别事件类型,例如:

stateMachine.Raise("Event");

或和Enum:

stateMachine.Raise(GameObject.Event);

但我觉得这两种方法都存在问题。字符串是两个灵活的,无法在编译时进行错误检查,以确保它们有效。枚举不能被扩展,限制扩展GameObject的每个类可用的事件,使事件调用更长时间不必要,并导致状态机内的类型检查问题。但是,使用类作为标识的方法意味着我在GameObject中声明事件,如下所示:

protected class SomeEvent : Event {}
protected class OtherEvent : Event {}
...
protected class AnotherEvent : Event {}

尽管优雅,但我觉得这在某种程度上会变成代码气味或可怕的做法,我得到的印象是我滥用了课程的目的。最终我将有数百个空类乱丢我的代码库,我可以看到它是一个潜在的问题。什么是最好的选择呢?

1 个答案:

答案 0 :(得分:1)

由于您正在为视频游戏而写作 - 除非这是游戏的一项功能 - 您的事件和状态应该在您的规范中定义,因此可能的事件列表一旦定义就不应该移动很多;所以去那些来自共同祖先的课程。

为什么不使用枚举或字符串?因为枚举和字符串不会携带数据。您通常希望将某些数据与您的活动相关联,因为它可以让您按家庭对活动进行分组。您不需要GrumpinessIncreaseEventJoyIncreaseEvent,而是MoodChangeEvent,其中包含一些信息(受影响的情绪类型,影响程度等)

你还可以拥有一些松散类型的事件,这些事件可以用于以后可能具有的潜在已知未知数(例如,具有对象属性的事件在运行时被转换为某种类型)


re:OP的评论:我的确认为你应该使用实例而不是类型。你不会通过PunchInFace而是new DamageEvent() {type = Damage.PUNCH, source= PuncherGuy.Fist, Target=PunchedGuy.Face},因为这种事件对游戏中的大量组件(物理引擎,得分引擎等)更友好......

再一次取决于游戏是如何完成的(这让我觉得这个问题实际上应该是关闭的,因为它是基于意见的)但是当你按类型提出PunchInFaceEvent时,你能说什么呢? ?谁打了谁?哪里?什么时候?等...