InputState.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // InputState.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using Microsoft.Xna.Framework;
  11. using Microsoft.Xna.Framework.Input;
  12. using Microsoft.Xna.Framework.Input.Touch;
  13. using System.Collections.Generic;
  14. #endregion
  15. namespace GameStateManagement
  16. {
  17. /// <summary>
  18. /// Helper for reading input from keyboard, gamepad, and touch input. This class
  19. /// tracks both the current and previous state of the input devices, and implements
  20. /// query methods for high level input actions such as "move up through the menu"
  21. /// or "pause the game".
  22. /// </summary>
  23. public class InputState
  24. {
  25. #region Fields
  26. public const int MaxInputs = 4;
  27. public readonly KeyboardState[] CurrentKeyboardStates;
  28. public readonly GamePadState[] CurrentGamePadStates;
  29. public readonly KeyboardState[] LastKeyboardStates;
  30. public readonly GamePadState[] LastGamePadStates;
  31. public readonly bool[] GamePadWasConnected;
  32. #if WINDOWS_PHONE || IOS || ANDROID
  33. public TouchCollection TouchState;
  34. public readonly List<GestureSample> Gestures = new List<GestureSample>();
  35. #endif
  36. #endregion
  37. #region Initialization
  38. /// <summary>
  39. /// Constructs a new input state.
  40. /// </summary>
  41. public InputState()
  42. {
  43. CurrentKeyboardStates = new KeyboardState[MaxInputs];
  44. CurrentGamePadStates = new GamePadState[MaxInputs];
  45. LastKeyboardStates = new KeyboardState[MaxInputs];
  46. LastGamePadStates = new GamePadState[MaxInputs];
  47. GamePadWasConnected = new bool[MaxInputs];
  48. }
  49. #endregion
  50. #region Public Methods
  51. /// <summary>
  52. /// Reads the latest state of the keyboard and gamepad.
  53. /// </summary>
  54. public void Update()
  55. {
  56. #if WINDOWS_PHONE || IOS || ANDROID
  57. TouchState = TouchPanel.GetState();
  58. Gestures.Clear();
  59. while (TouchPanel.IsGestureAvailable)
  60. {
  61. Gestures.Add(TouchPanel.ReadGesture());
  62. }
  63. #else
  64. for (int i = 0; i < MaxInputs; i++)
  65. {
  66. LastKeyboardStates[i] = CurrentKeyboardStates[i];
  67. LastGamePadStates[i] = CurrentGamePadStates[i];
  68. CurrentKeyboardStates[i] = Keyboard.GetState((PlayerIndex)i);
  69. CurrentGamePadStates[i] = GamePad.GetState((PlayerIndex)i);
  70. // Keep track of whether a gamepad has ever been
  71. // connected, so we can detect if it is unplugged.
  72. if (CurrentGamePadStates[i].IsConnected)
  73. {
  74. GamePadWasConnected[i] = true;
  75. }
  76. }
  77. #endif
  78. }
  79. /// <summary>
  80. /// Helper for checking if a key was newly pressed during this update. The
  81. /// controllingPlayer parameter specifies which player to read input for.
  82. /// If this is null, it will accept input from any player. When a keypress
  83. /// is detected, the output playerIndex reports which player pressed it.
  84. /// </summary>
  85. public bool IsNewKeyPress(Keys key, PlayerIndex? controllingPlayer,
  86. out PlayerIndex playerIndex)
  87. {
  88. if (controllingPlayer.HasValue)
  89. {
  90. // Read input from the specified player.
  91. playerIndex = controllingPlayer.Value;
  92. int i = (int)playerIndex;
  93. return (CurrentKeyboardStates[i].IsKeyDown(key) &&
  94. LastKeyboardStates[i].IsKeyUp(key));
  95. }
  96. else
  97. {
  98. // Accept input from any player.
  99. return (IsNewKeyPress(key, PlayerIndex.One, out playerIndex) ||
  100. IsNewKeyPress(key, PlayerIndex.Two, out playerIndex) ||
  101. IsNewKeyPress(key, PlayerIndex.Three, out playerIndex) ||
  102. IsNewKeyPress(key, PlayerIndex.Four, out playerIndex));
  103. }
  104. }
  105. /// <summary>
  106. /// Helper for checking if a button was newly pressed during this update.
  107. /// The controllingPlayer parameter specifies which player to read input for.
  108. /// If this is null, it will accept input from any player. When a button press
  109. /// is detected, the output playerIndex reports which player pressed it.
  110. /// </summary>
  111. public bool IsNewButtonPress(Buttons button, PlayerIndex? controllingPlayer,
  112. out PlayerIndex playerIndex)
  113. {
  114. if (controllingPlayer.HasValue)
  115. {
  116. // Read input from the specified player.
  117. playerIndex = controllingPlayer.Value;
  118. int i = (int)playerIndex;
  119. return (CurrentGamePadStates[i].IsButtonDown(button) &&
  120. LastGamePadStates[i].IsButtonUp(button));
  121. }
  122. else
  123. {
  124. // Accept input from any player.
  125. return (IsNewButtonPress(button, PlayerIndex.One, out playerIndex) ||
  126. IsNewButtonPress(button, PlayerIndex.Two, out playerIndex) ||
  127. IsNewButtonPress(button, PlayerIndex.Three, out playerIndex) ||
  128. IsNewButtonPress(button, PlayerIndex.Four, out playerIndex));
  129. }
  130. }
  131. /// <summary>
  132. /// Checks for a "menu select" input action.
  133. /// The controllingPlayer parameter specifies which player to read input for.
  134. /// If this is null, it will accept input from any player. When the action
  135. /// is detected, the output playerIndex reports which player pressed it.
  136. /// </summary>
  137. public bool IsMenuSelect(PlayerIndex? controllingPlayer,
  138. out PlayerIndex playerIndex)
  139. {
  140. return IsNewKeyPress(Keys.Space, controllingPlayer, out playerIndex) ||
  141. IsNewKeyPress(Keys.Enter, controllingPlayer, out playerIndex) ||
  142. IsNewButtonPress(Buttons.A, controllingPlayer, out playerIndex) ||
  143. IsNewButtonPress(Buttons.Start, controllingPlayer, out playerIndex);
  144. }
  145. /// <summary>
  146. /// Checks for a "menu cancel" input action.
  147. /// The controllingPlayer parameter specifies which player to read input for.
  148. /// If this is null, it will accept input from any player. When the action
  149. /// is detected, the output playerIndex reports which player pressed it.
  150. /// </summary>
  151. public bool IsMenuCancel(PlayerIndex? controllingPlayer,
  152. out PlayerIndex playerIndex)
  153. {
  154. return IsNewKeyPress(Keys.Escape, controllingPlayer, out playerIndex) ||
  155. IsNewButtonPress(Buttons.B, controllingPlayer, out playerIndex) ||
  156. IsNewButtonPress(Buttons.Back, controllingPlayer, out playerIndex);
  157. }
  158. /// <summary>
  159. /// Checks for a "menu up" input action.
  160. /// The controllingPlayer parameter specifies which player to read
  161. /// input for. If this is null, it will accept input from any player.
  162. /// </summary>
  163. public bool IsMenuUp(PlayerIndex? controllingPlayer)
  164. {
  165. PlayerIndex playerIndex;
  166. return IsNewKeyPress(Keys.Up, controllingPlayer, out playerIndex) ||
  167. IsNewKeyPress(Keys.Left, controllingPlayer, out playerIndex) ||
  168. IsNewButtonPress(Buttons.DPadLeft, controllingPlayer, out playerIndex) ||
  169. IsNewButtonPress(Buttons.LeftThumbstickLeft, controllingPlayer, out playerIndex);
  170. }
  171. /// <summary>
  172. /// Checks for a "menu down" input action.
  173. /// The controllingPlayer parameter specifies which player to read
  174. /// input for. If this is null, it will accept input from any player.
  175. /// </summary>
  176. public bool IsMenuDown(PlayerIndex? controllingPlayer)
  177. {
  178. PlayerIndex playerIndex;
  179. return IsNewKeyPress(Keys.Down, controllingPlayer, out playerIndex) ||
  180. IsNewKeyPress(Keys.Right, controllingPlayer, out playerIndex) ||
  181. IsNewButtonPress(Buttons.DPadRight, controllingPlayer, out playerIndex) ||
  182. IsNewButtonPress(Buttons.LeftThumbstickRight, controllingPlayer, out playerIndex);
  183. }
  184. /// <summary>
  185. /// Checks for a "pause the game" input action.
  186. /// The controllingPlayer parameter specifies which player to read
  187. /// input for. If this is null, it will accept input from any player.
  188. /// </summary>
  189. public bool IsPauseGame(PlayerIndex? controllingPlayer)
  190. {
  191. PlayerIndex playerIndex;
  192. return IsNewKeyPress(Keys.Escape, controllingPlayer, out playerIndex) ||
  193. IsNewButtonPress(Buttons.Back, controllingPlayer, out playerIndex) ||
  194. IsNewButtonPress(Buttons.Start, controllingPlayer, out playerIndex);
  195. }
  196. #endregion
  197. }
  198. }