InputState.cs 8.1 KB

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