Я играю с изучением 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();
и другие классы, например, класс, соответствующий меню, могут добавлять свои собственные перечисления к этому глобальному Enum, так что каждый набор возможных действий определяется внутри каждого класса, отвечающего за обработку ввода, вместо того, чтобы быть предопределенным в глобальном перечислении.
Но я не могу этого сделать, потому что я не могу добавлять или удалять из перечисления и не могу наследовать от 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 и привести все перечисления моего другого класса к целым, чтобы я мог или действовать вместе, но это не обеспечивает безопасность типов перечислений.
Итак, мои вопросы:
Есть ли способ сделать это с помощью перечислений?
Есть ли более умный способ делать подобные вещи вообще (с помощью перечислений или другим способом полностью)?
Я делаю это, чтобы выучить язык, поэтому я был бы признателен за комментарии, если есть намного лучший способ сделать что-то подобное!