我正在考虑实现一个定义游戏对象状态的枚举,我想知道我是否可以在枚举的定义中直接使用标志,而不是将对象的状态定义为标志的集合,不容易,状态机中使用的状态的预定义全局名称。
例如,假设有5种状态:PreActivation(创建但未启动;即未来波中的敌人),活动(当前正在使用;即屏幕上的敌人,攻击你),暂停(不再活跃的,但可能会重新激活;即如果玩家使用时间冻结的力量,则为敌人),DeActivated(已完成使用但仍在游戏世界中的物体;即死亡后身体遗留的敌人,如在毁灭战士1& 2)和ToRemove(一个用于从游戏中移除的物体;即在你清除一个等级并移动到下一个等级后的敌人)。
我想要做的是定义枚举,以便状态包含所有适用的标志;例如,DeActivated敌人:1。先前已被激活,2。目前尚未激活。我目前的想法是做这样的事情:
public enum ObjectState
{
// The first section are the flags
BeenActivated = 0b0000001, // Previously activated
CurrentlyActive = 0b0000010, // Currently activated
IsSuspended = 0b0000100, // It may be reactivated
ShouldRemove = 0b0001000, // It should be removed
// These are the states
PreActivation = 0b0000100, // Mot currently active, nor has it ever been active, but it will get activated
Active = 0b0000011, // Currently active, and it's been active
Paused = 0b0000101, // Not currently active, but it's been active before
DeActivated = 0b0000001, // Not currently active, but it's been active before, and it shouldn't get reactivated, but don't remove yet
ToRemove = 0b0001001 // Not currently active, but it's been active before, and it shouldn't get reactivated, it should be removed
}
据我所知,这应该可以正常工作,但我有几个主要问题:
很抱歉,如果这是重复,或者我违反了其他规则,但我今天刚创建了一个帐户;这是我的第一篇文章。另外,我不确定在搜索时你会怎么称呼它,而且我没有从这里或谷歌获得任何类似的点击。
答案 0 :(得分:13)
你可以这样做。它是旗帜枚举的重点。如果enum
旨在用作标记,请使用[Flags]
属性标记它。
我建议将现有标志与按位或(|
)组合起来。它更具可读性且不易出错。
[Flags]
public enum ObjectState
{
// Flags
BeenActivated = 0b0000001, // Previously activated
CurrentlyActive = 0b0000010, // Currently activated
IsSuspended = 0b0000100, // It may be reactivated
ShouldRemove = 0b0001000, // It should be removed
// States as combination of flags.
PreActivationState = IsSuspended, // Mot currently active, nor has it ever been active, but it will get activated
ActiveState = BeenActivated | CurrentlyActive, // Currently active, and it's been active
PausedState = BeenActivated | IsSuspended, // Not currently active, but it's been active before
DeActivatedState = BeenActivated, // Not currently active, but it's been active before, and it shouldn't get reactivated, but don't remove yet
ToRemoveState = BeenActivated | ShouldRemove // Not currently active, but it's been active before, and it shouldn't get reactivated, it should be removed
}
我还添加了一个"州"州的后缀,以更好地区分它们与旗帜。或转过身来添加一个" Flags"而不是标志的后缀。
答案 1 :(得分:4)
您考虑使用[Flags]-enum吗?
[Flags]
public enum ObjectState
{
BeenActivated = 1, // Previously activated
CurrentlyActive = 2, // Currently activated
IsSuspended = 4, // It may be reactivated
ShouldRemove = 8, // It should be removed
}
// Currently active, and it's been active
var active = ObjectState.BeenActivated | ObjectState.CurrentlyActive;
答案 2 :(得分:1)
如果没有更多的上下文,很难真正知道,但是您可能希望查看State Pattern以获得更具扩展性和OO的处理方式。
它的工作方式是让你的游戏对象成为一个空shell,实现抽象Game State类所做的相同界面。游戏对象将调用状态来执行接口指定的操作,而状态具有对其包含的游戏对象的引用。当状态改变时,状态实例告诉游戏对象。
因此,举例来说,让我们说你的游戏对象只有一个方法的接口,"攻击"。抽象状态类有两个具体的子类,Alive和Dead。 Alive and Dead也实施了Attack。当某些东西攻击你的游戏对象时,object.Attack(); ,对象内部只调用state.Attack()。 Alive状态将决定攻击是否成功并执行parent.State = new DeadState();.当再次调用攻击时,DeadState什么都不做。
这样你可以避免使用枚举,开关,ifs,所有内容,只需添加游戏状态而无需进一步编程。你的被激活了#34; check也是一种接口方法。