#region File Description //----------------------------------------------------------------------------- // InputState.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input.Touch; using FarseerPhysics.SamplesFramework; namespace GameStateManagement { /// /// Helper for reading input from keyboard, gamepad, and touch input. This class /// tracks both the current and previous state of the input devices, and implements /// query methods for high level input actions such as "move up through the menu" /// or "pause the game". /// public class InputState { public const int MaxInputs = 4; public readonly KeyboardState[] CurrentKeyboardStates; public readonly GamePadState[] CurrentGamePadStates; public readonly KeyboardState[] LastKeyboardStates; public readonly GamePadState[] LastGamePadStates; public readonly bool[] GamePadWasConnected; /* * Needed for virtual stick on WP7 * -- Nathan Adams [adamsna@datanethost.net] - 4/12/2012 */ private GamePadState _currentVirtualState; private GamePadState _lastVirtualState; private bool _handleVirtualStick; /* * I didn't create an array for the virtual stick because there will only be one * -- Nathan Adams [adamsna@datanethost.net] - 4/12/2012 */ /* * * * * * */ private Vector2 _cursor; private bool _cursorIsValid; private bool _cursorIsVisible; private bool _cursorMoved; private Sprite _cursorSprite; #if WINDOWS_PHONE private VirtualStick _phoneStick; private VirtualButton _phoneA; private VirtualButton _phoneB; #endif public TouchCollection TouchState; public readonly List Gestures = new List(); /// /// Constructs a new input state. /// public InputState() { CurrentKeyboardStates = new KeyboardState[MaxInputs]; CurrentGamePadStates = new GamePadState[MaxInputs]; LastKeyboardStates = new KeyboardState[MaxInputs]; LastGamePadStates = new GamePadState[MaxInputs]; GamePadWasConnected = new bool[MaxInputs]; } /// /// Reads the latest state user input. /// public void Update() { for (int i = 0; i < MaxInputs; i++) { LastKeyboardStates[i] = CurrentKeyboardStates[i]; LastGamePadStates[i] = CurrentGamePadStates[i]; CurrentKeyboardStates[i] = Keyboard.GetState((PlayerIndex)i); CurrentGamePadStates[i] = GamePad.GetState((PlayerIndex)i); // Keep track of whether a gamepad has ever been // connected, so we can detect if it is unplugged. if (CurrentGamePadStates[i].IsConnected) { GamePadWasConnected[i] = true; } } // Get the raw touch state from the TouchPanel TouchState = TouchPanel.GetState(); // Read in any detected gestures into our list for the screens to later process Gestures.Clear(); while (TouchPanel.IsGestureAvailable) { Gestures.Add(TouchPanel.ReadGesture()); } } /// /// Helper for checking if a key was pressed during this update. The /// controllingPlayer parameter specifies which player to read input for. /// If this is null, it will accept input from any player. When a keypress /// is detected, the output playerIndex reports which player pressed it. /// public bool IsKeyPressed(Keys key, PlayerIndex? controllingPlayer, out PlayerIndex playerIndex) { if (controllingPlayer.HasValue) { // Read input from the specified player. playerIndex = controllingPlayer.Value; int i = (int)playerIndex; return CurrentKeyboardStates[i].IsKeyDown(key); } else { // Accept input from any player. return (IsKeyPressed(key, PlayerIndex.One, out playerIndex) || IsKeyPressed(key, PlayerIndex.Two, out playerIndex) || IsKeyPressed(key, PlayerIndex.Three, out playerIndex) || IsKeyPressed(key, PlayerIndex.Four, out playerIndex)); } } /// /// Helper for checking if a button was pressed during this update. /// The controllingPlayer parameter specifies which player to read input for. /// If this is null, it will accept input from any player. When a button press /// is detected, the output playerIndex reports which player pressed it. /// public bool IsButtonPressed(Buttons button, PlayerIndex? controllingPlayer, out PlayerIndex playerIndex) { if (controllingPlayer.HasValue) { // Read input from the specified player. playerIndex = controllingPlayer.Value; int i = (int)playerIndex; return CurrentGamePadStates[i].IsButtonDown(button); } else { // Accept input from any player. return (IsButtonPressed(button, PlayerIndex.One, out playerIndex) || IsButtonPressed(button, PlayerIndex.Two, out playerIndex) || IsButtonPressed(button, PlayerIndex.Three, out playerIndex) || IsButtonPressed(button, PlayerIndex.Four, out playerIndex)); } } /// /// Helper for checking if a key was newly pressed during this update. The /// controllingPlayer parameter specifies which player to read input for. /// If this is null, it will accept input from any player. When a keypress /// is detected, the output playerIndex reports which player pressed it. /// public bool IsNewKeyPress(Keys key, PlayerIndex? controllingPlayer, out PlayerIndex playerIndex) { if (controllingPlayer.HasValue) { // Read input from the specified player. playerIndex = controllingPlayer.Value; int i = (int)playerIndex; return (CurrentKeyboardStates[i].IsKeyDown(key) && LastKeyboardStates[i].IsKeyUp(key)); } else { // Accept input from any player. return (IsNewKeyPress(key, PlayerIndex.One, out playerIndex) || IsNewKeyPress(key, PlayerIndex.Two, out playerIndex) || IsNewKeyPress(key, PlayerIndex.Three, out playerIndex) || IsNewKeyPress(key, PlayerIndex.Four, out playerIndex)); } } /// /// Helper for checking if a button was newly pressed during this update. /// The controllingPlayer parameter specifies which player to read input for. /// If this is null, it will accept input from any player. When a button press /// is detected, the output playerIndex reports which player pressed it. /// public bool IsNewButtonPress(Buttons button, PlayerIndex? controllingPlayer, out PlayerIndex playerIndex) { if (controllingPlayer.HasValue) { // Read input from the specified player. playerIndex = controllingPlayer.Value; int i = (int)playerIndex; return (CurrentGamePadStates[i].IsButtonDown(button) && LastGamePadStates[i].IsButtonUp(button)); } else { // Accept input from any player. return (IsNewButtonPress(button, PlayerIndex.One, out playerIndex) || IsNewButtonPress(button, PlayerIndex.Two, out playerIndex) || IsNewButtonPress(button, PlayerIndex.Three, out playerIndex) || IsNewButtonPress(button, PlayerIndex.Four, out playerIndex)); } } } }