InputState.cs 8.8 KB

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