高效且可扩展地将游戏手柄输入转换为游戏逻辑输入

时间:2016-10-22 14:24:15

标签: c# xna monogame opentk

我正在尝试创建一个接受OpenTK的GamePad或GamePadState对象的函数,并输出一个由[Flags] Enum组成的结构,其中包含基于输入映射(字典?)的游戏及其状态的所有有意义的输入。这个想法是地图可以任意改变以允许简单的输入重新配置,我可以通过枚举分配输入有用名称的有意义的组合,并使用位标志用于时髦的其他东西。这听起来像是以这种方式建立起来非常有用。

似乎它应该是可能的,但不幸的是我现在已经尝试了几次,并且每次出现一团糟。我可以得到一些关于如何构建这个的建议吗?

这就是我目前正在尝试的事情:

Inputs.cs

namespace F1.Input
{
  [Flags]
  public enum Inputs
  {
    None = 0,
    Up = 1,
    Down = 2,
    Left = 4,
    Right = 8,
    Neutral = -16, // ?
    D1 = 6,
    D2 = 2,
    D3 = 10,
    D4 = 4,
    D5 = -16,
    D6 = 8,
    D7 = 5,
    D8 = 1,
    D9 = 9,
    A = 16,
    B = 32,
    C = 64,
    D = 128,
    Start = 256,
    Accept = 512,
    Cancel = 1024,
  }
}

GameInputs.cs

namespace F1.Input
{
  public struct GameInputs : IEquatable<GameInputs>
  {
    Inputs inputs;

    public GameInputs(Inputs state)
    {
      inputs = state;
    }

    public InputState None { get { return GetInput(Inputs.None); } }
    public InputState Up { get { return GetInput(Inputs.Up); } }
    public InputState Down { get { return GetInput(Inputs.Down); } }
    public InputState Left { get { return GetInput(Inputs.Left); } }
    public InputState Right { get { return GetInput(Inputs.Right); } }
    public InputState Neutral { get { return GetInput(Inputs.Neutral); } }
    public InputState D1 { get { return GetInput(Inputs.D1); } }
    public InputState D2 { get { return GetInput(Inputs.D2); } }
    public InputState D3 { get { return GetInput(Inputs.D3); } }
    public InputState D4 { get { return GetInput(Inputs.D4); } }
    public InputState D5 { get { return GetInput(Inputs.D5); } }
    public InputState D6 { get { return GetInput(Inputs.D6); } }
    public InputState D7 { get { return GetInput(Inputs.D7); } }
    public InputState D8 { get { return GetInput(Inputs.D8); } }
    public InputState D9 { get { return GetInput(Inputs.D9); } }
    public InputState A { get { return GetInput(Inputs.A); } }
    public InputState B { get { return GetInput(Inputs.B); } }
    public InputState C { get { return GetInput(Inputs.C); } }
    public InputState D { get { return GetInput(Inputs.D); } }
    public InputState Start { get { return GetInput(Inputs.Start); } }
    public InputState Accept { get { return GetInput(Inputs.Accept); } }
    public InputState Cancel { get { return GetInput(Inputs.Cancel); } }

    #region IEquatable<GameInputs> Members

    public bool Equals(GameInputs other)
    {
      return inputs == other.inputs;
    }

    #endregion

    #region Private Members

    InputState GetInput(Inputs i)
    {
      return (inputs & i) != 0 ? InputState.Active : InputState.Inactive;
    }

    #endregion
  }
}

Input.cs

using F1.Input;
using OpenTK.Input;
using System;
using System.Collections.Generic;

namespace F1
{
  class F1Input
  {
    public Dictionary<GamePadButtons, GameInputs> buttonMap { get; set; }
    public Dictionary<GamePadDPad, GameInputs> directionMap { get; set; }
    public int gamePadIndex { get; set; }
    internal GamePadButtons gamePadButtons { get; set; }
    internal GamePadDPad gamePadDPad { get; set; }
    internal GameInputs gameInputButtons { get; set; }
    internal GameInputs gameInputDPad { get; set; }

    public F1Input(Dictionary<GamePadButtons, GameInputs> inputMap, int gamePadIndex)
    {
      this.buttonMap = DefaultButtonMapping();
      this.directionMap = DefaultDirectionMapping();
      this.gamePadIndex = gamePadIndex;
    }

    public void Update() {
      gamePadButtons = GamePad.GetState(gamePadIndex).Buttons;
      gamePadDPad = GamePad.GetState(gamePadIndex).DPad;
      GameInputs dictOut;
      buttonMap.TryGetValue(gamePadButtons, out dictOut);
      gameInputButtons = dictOut;
      directionMap.TryGetValue(gamePadDPad, out dictOut);
      gameInputDPad = dictOut;
    }

    public GameInputs getGameInputs()
    {
      return gameInputButtons;
    }

    private Dictionary<GamePadDPad, GameInputs> DefaultDirectionMapping()
    {
      return new Dictionary<GamePadDPad, GameInputs>()
      {
        // It was about here that I realized something is very wrong with my architecture.
      };
    }
    private Dictionary<GamePadButtons, GameInputs> DefaultButtonMapping()
    {
      return new Dictionary<GamePadButtons, GameInputs>()
      {
        { new GamePadButtons(Buttons.A), new GameInputs(Inputs.A) },
        { new GamePadButtons(Buttons.B), new GameInputs(Inputs.B) },
        { new GamePadButtons(Buttons.X), new GameInputs(Inputs.C) },
        { new GamePadButtons(Buttons.Y), new GameInputs(Inputs.D) }
      };
    }
  }
}

这不起作用,因为(除其他外)输入组合不起作用,可能是因为我正在使用字典。

0 个答案:

没有答案