我正在玩一个小游戏来学习C#。作为其中的一部分,我将输入从设备映射到包含游戏内动作的枚举,从按钮字典,动作对定义。
例如,我有类似的东西:
[Flags]
enum Actions { None=0, MoveUp=1, MoveDown=2, MoveLeft=4, MoveRight=8 }
Actions currentActions;
private void SetActions()
{
currentActions = Actions.None;
if (UpPressed)
currentAction |= Actions.MoveUp;
(etc)
}
public void Update()
{
SetActions();
if (currentActions & Actions.MoveUp) == Actions.MoveUp)
MoveUp();
(etc)
}
我根据输入设置动作,然后根据列表中的动作更新游戏的状态。
我想做的是,有一个新类,“ActionManager”,其中包含与动作相关的数据和方法;
public Enum currentActions;
public void SetActions();
public void UpdateActions();
和其他类,例如,对应于菜单的类,可以将它们自己的枚举添加到此全局枚举中,以便在负责处理输入的每个类内部定义每组可能的动作,而不是预定义在全球的枚举中。
但我不能这样做,因为我无法添加或删除枚举,我无法从System.Enum继承。我能想到的唯一方法是使用枚举列表:
// In class ActionManager
public List<Enum> allowedActions = new List<Enum>();
public List<Enum> currentActions = new List<Enum>();
public void SetActions(Enum action)
{
currentActions.Clear();
foreach (Enum e in allowedActions)
if (IsKeyPressed(e))
currentActions.Add(e);
}
// In, say, GameMenu class
[Flags]
enum MenuActions { None=0, MenuUp = 1, ... }
private actionManager ActionManager = new ActionManager();
public void DefineActions()
{
foreach (MenuActions m in Enum.GetValues(typeof(MenuActions)))
actionManager.allowedActions.Add(m);
//also define the key corresponding to the action
//here, from e.g., a config file
//and put this into a Dictionary<buttons, actions>
}
public Update()
{
actionManager.Update();
if (actionManager.currentActions.Contains(MenuActions.MenuUp))
(etc)
}
但这看起来很愚蠢,我用一个Enums列表取代了廉价的逻辑操作,这看起来很尴尬。它还迫使我使用.Contains等而不是算术,并使用值类型更有意义的引用类型(并且通用列表不应该暴露给外部)。
我意识到我也可以用int替换我的List,并将我所有其他类的枚举转换为int,这样我就可以或者一起行动,但是它没有枚举类型的安全性。
所以,我的问题是: 有没有办法用枚举做到这一点? 是否有一种更聪明的方法来做这种事情(无论是使用枚举还是其他方式)?
我这样做是为了学习这门语言,所以如果有更好的方法可以做这样的话,我会感激评论!
答案 0 :(得分:3)
是;你可以使用位运算符:
Actions allowedActions = Actions.Up | Actions.Right;
allowedActions |= Actions.Down; // to show building at runtime
Actions currentActions = Actions.Right | Actions.Down; // union
然后使用各种&
/ |
/ ~
来执行测试和更改:
var limitedToAllowed = currentActions & allowedActions; // intersect
// disallow "up" for some reason
allowedActions &= ~Actions.Up;
您可以通过以下方式测试重叠:
// test if **any** of the currentActions is in the allowedActions
bool anyAllowed = currentActions & allowedActions != 0;
// test if **all** of the currentActions are in the allowedActions
bool allAllowed = currentActions & allowedActions == currentActions;
关于“允许哪些值”的说明通常可以通过添加.All
枚举(在您的情况下为15)或在运行时完成:
Actions actions = 0;
foreach(Actions action in Enum.GetValues(typeof(Actions))) {
actions |= action;
}
// actions now has all the flags that are defined