InputAction.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // InputAction.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. using System;
  10. using Microsoft.Xna.Framework;
  11. using Microsoft.Xna.Framework.Input;
  12. namespace GameStateManagement
  13. {
  14. /// <summary>
  15. /// Defines an action that is designated by some set of buttons and/or keys.
  16. ///
  17. /// The way actions work is that you define a set of buttons and keys that trigger the action. You can
  18. /// then evaluate the action against an InputState which will test to see if any of the buttons or keys
  19. /// are pressed by a player. You can also set a flag that indicates if the action only occurs once when
  20. /// the buttons/keys are first pressed or whether the action should occur each frame.
  21. ///
  22. /// Using this InputAction class means that you can configure new actions based on keys and buttons
  23. /// without having to directly modify the InputState type. This means more customization by your games
  24. /// without having to change the core classes of Game State Management.
  25. /// </summary>
  26. public class InputAction
  27. {
  28. private readonly Buttons[] buttons;
  29. private readonly Keys[] keys;
  30. private readonly bool newPressOnly;
  31. // These delegate types map to the methods on InputState. We use these to simplify the evalute method
  32. // by allowing us to map the appropriate delegates and invoke them, rather than having two separate code paths.
  33. private delegate bool ButtonPress(Buttons button, PlayerIndex? controllingPlayer, out PlayerIndex player);
  34. private delegate bool KeyPress(Keys key, PlayerIndex? controllingPlayer, out PlayerIndex player);
  35. /// <summary>
  36. /// Initializes a new InputAction.
  37. /// </summary>
  38. /// <param name="buttons">An array of buttons that can trigger the action.</param>
  39. /// <param name="keys">An array of keys that can trigger the action.</param>
  40. /// <param name="newPressOnly">Whether the action only occurs on the first press of one of the buttons/keys,
  41. /// false if it occurs each frame one of the buttons/keys is down.</param>
  42. public InputAction(Buttons[] buttons, Keys[] keys, bool newPressOnly)
  43. {
  44. // Store the buttons and keys. If the arrays are null, we create a 0 length array so we don't
  45. // have to do null checks in the Evaluate method
  46. this.buttons = buttons != null ? buttons.Clone() as Buttons[] : new Buttons[0];
  47. this.keys = keys != null ? keys.Clone() as Keys[] : new Keys[0];
  48. this.newPressOnly = newPressOnly;
  49. }
  50. /// <summary>
  51. /// Evaluates the action against a given InputState.
  52. /// </summary>
  53. /// <param name="state">The InputState to test for the action.</param>
  54. /// <param name="controllingPlayer">The player to test, or null to allow any player.</param>
  55. /// <param name="player">If controllingPlayer is null, this is the player that performed the action.</param>
  56. /// <returns>True if the action occurred, false otherwise.</returns>
  57. public bool Evaluate(InputState state, PlayerIndex? controllingPlayer, out PlayerIndex player)
  58. {
  59. // Figure out which delegate methods to map from the state which takes care of our "newPressOnly" logic
  60. ButtonPress buttonTest;
  61. KeyPress keyTest;
  62. if (newPressOnly)
  63. {
  64. buttonTest = state.IsNewButtonPress;
  65. keyTest = state.IsNewKeyPress;
  66. }
  67. else
  68. {
  69. buttonTest = state.IsButtonPressed;
  70. keyTest = state.IsKeyPressed;
  71. }
  72. // Now we simply need to invoke the appropriate methods for each button and key in our collections
  73. foreach (Buttons button in buttons)
  74. {
  75. if (buttonTest(button, controllingPlayer, out player))
  76. return true;
  77. }
  78. foreach (Keys key in keys)
  79. {
  80. if (keyTest(key, controllingPlayer, out player))
  81. return true;
  82. }
  83. // If we got here, the action is not matched
  84. player = PlayerIndex.One;
  85. return false;
  86. }
  87. }
  88. }