axiosengine/axios/ScreenSystem/InputState.cs

431 lines
15 KiB
C#
Raw Normal View History

#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.Content;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using FarseerPhysics.SamplesFramework;
using Microsoft.Xna.Framework.Graphics;
namespace GameStateManagement
{
/// <summary>
/// an enum of all available mouse buttons.
/// </summary>
public enum MouseButtons
{
LeftButton,
MiddleButton,
RightButton,
ExtraButton1,
ExtraButton2
}
/// <summary>
/// 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".
/// </summary>
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
*/
/*
* Adding variables for the cursor
* -- Nathan Adams [adamsna@datanethost.net] - 4/15/2012
*
*/
private MouseState _currentMouseState;
private MouseState _lastMouseState;
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<GestureSample> Gestures = new List<GestureSample>();
private ScreenManager _manager;
private Viewport _viewport;
/// <summary>
/// Constructs a new input state.
/// </summary>
public InputState(ScreenManager manager)
{
_manager = manager;
CurrentKeyboardStates = new KeyboardState[MaxInputs];
CurrentGamePadStates = new GamePadState[MaxInputs];
LastKeyboardStates = new KeyboardState[MaxInputs];
LastGamePadStates = new GamePadState[MaxInputs];
GamePadWasConnected = new bool[MaxInputs];
_currentVirtualState = new GamePadState();
_lastVirtualState = new GamePadState();
_cursorIsVisible = false;
_cursorMoved = false;
#if WINDOWS_PHONE
_cursorIsValid = false;
#else
_cursorIsValid = true;
#endif
_cursor = Vector2.Zero;
_handleVirtualStick = false;
}
public MouseState MouseState
{
get { return _currentMouseState; }
}
public GamePadState VirtualState
{
get { return _currentVirtualState; }
}
public MouseState PreviousMouseState
{
get { return _lastMouseState; }
}
public GamePadState PreviousVirtualState
{
get { return _lastVirtualState; }
}
public bool ShowCursor
{
get { return _cursorIsVisible && _cursorIsValid; }
set { _cursorIsVisible = value; }
}
public bool EnableVirtualStick
{
get { return _handleVirtualStick; }
set { _handleVirtualStick = value; }
}
public Vector2 Cursor
{
get { return _cursor; }
}
public bool IsCursorMoved
{
get { return _cursorMoved; }
}
public bool IsCursorValid
{
get { return _cursorIsValid; }
}
public void LoadContent()
{
ContentManager man = new ContentManager(_manager.Game.Services, "Content");
_cursorSprite = new Sprite(man.Load<Texture2D>("Common/cursor"));
#if WINDOWS_PHONE
// virtual stick content
_phoneStick = new VirtualStick(man.Load<Texture2D>("Common/socket"),
man.Load<Texture2D>("Common/stick"), new Vector2(80f, 400f));
Texture2D temp = man.Load<Texture2D>("Common/buttons");
_phoneA = new VirtualButton(temp, new Vector2(695f, 380f), new Rectangle(0, 0, 40, 40), new Rectangle(0, 40, 40, 40));
_phoneB = new VirtualButton(temp, new Vector2(745f, 360f), new Rectangle(40, 0, 40, 40), new Rectangle(40, 40, 40, 40));
#endif
_viewport = _manager.GraphicsDevice.Viewport;
}
private GamePadState HandleVirtualStickWin()
{
Vector2 _leftStick = Vector2.Zero;
List<Buttons> _buttons = new List<Buttons>();
PlayerIndex pout;
if (IsNewKeyPress(Keys.A, PlayerIndex.One, out pout))
{
_leftStick.X -= 1f;
}
if (IsNewKeyPress(Keys.S, PlayerIndex.One, out pout))
{
_leftStick.Y -= 1f;
}
if (IsNewKeyPress(Keys.D, PlayerIndex.One, out pout))
{
_leftStick.X += 1f;
}
if (IsNewKeyPress(Keys.W, PlayerIndex.One, out pout))
{
_leftStick.Y += 1f;
}
if (IsNewKeyPress(Keys.Space, PlayerIndex.One, out pout))
{
_buttons.Add(Buttons.A);
}
if (IsNewKeyPress(Keys.LeftControl, PlayerIndex.One, out pout))
{
_buttons.Add(Buttons.B);
}
if (_leftStick != Vector2.Zero)
{
_leftStick.Normalize();
}
return new GamePadState(_leftStick, Vector2.Zero, 0f, 0f, _buttons.ToArray());
}
private GamePadState HandleVirtualStickWP7()
{
List<Buttons> _buttons = new List<Buttons>();
Vector2 _stick = Vector2.Zero;
#if WINDOWS_PHONE
_phoneA.Pressed = false;
_phoneB.Pressed = false;
TouchCollection touchLocations = TouchPanel.GetState();
foreach (TouchLocation touchLocation in touchLocations)
{
_phoneA.Update(touchLocation);
_phoneB.Update(touchLocation);
_phoneStick.Update(touchLocation);
}
if (_phoneA.Pressed)
{
_buttons.Add(Buttons.A);
}
if (_phoneB.Pressed)
{
_buttons.Add(Buttons.B);
}
_stick = _phoneStick.StickPosition;
#endif
return new GamePadState(_stick, Vector2.Zero, 0f, 0f, _buttons.ToArray());
}
/// <summary>
/// Reads the latest state user input.
/// </summary>
public void Update()
{
_lastMouseState = _currentMouseState;
if (_handleVirtualStick)
{
_lastVirtualState = _currentVirtualState;
}
_currentMouseState = Mouse.GetState();
if (_handleVirtualStick)
{
#if XBOX
_currentVirtualState= GamePad.GetState(PlayerIndex.One);
#elif WINDOWS
if (GamePad.GetState(PlayerIndex.One).IsConnected)
{
_currentVirtualState = GamePad.GetState(PlayerIndex.One);
}
else
{
_currentVirtualState = HandleVirtualStickWin();
}
#elif WINDOWS_PHONE
_currentVirtualState = HandleVirtualStickWP7();
#endif
}
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());
}
}
/// <summary>
/// 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.
/// </summary>
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));
}
}
/// <summary>
/// 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.
/// </summary>
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));
}
}
/// <summary>
/// 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.
/// </summary>
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));
}
}
/// <summary>
/// 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.
/// </summary>
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));
}
}
public bool IsNewVirtualButtonPress(Buttons button)
{
return (_lastVirtualState.IsButtonUp(button) &&
_currentVirtualState.IsButtonDown(button));
}
public bool IsNewVirtualButtonRelease(Buttons button)
{
return (_lastVirtualState.IsButtonDown(button) &&
_currentVirtualState.IsButtonUp(button));
}
}
}