axiosengine/axios/ScreenSystem/InputHelper.cs

473 lines
16 KiB
C#

using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using FarseerPhysics.SamplesFramework;
using GameStateManagement;
namespace FarseerPhysics.SamplesFramework2
{
/// <summary>
/// an enum of all available mouse buttons.
/// </summary>
public enum MouseButtons
{
LeftButton,
MiddleButton,
RightButton,
ExtraButton1,
ExtraButton2
}
public class InputHelper
{
private readonly List<GestureSample> _gestures = new List<GestureSample>();
private GamePadState _currentGamePadState;
private KeyboardState _currentKeyboardState;
private MouseState _currentMouseState;
private GamePadState _currentVirtualState;
private GamePadState _lastGamePadState;
private KeyboardState _lastKeyboardState;
private MouseState _lastMouseState;
private GamePadState _lastVirtualState;
private bool _handleVirtualStick;
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
private ScreenManager _manager;
private Viewport _viewport;
/// <summary>
/// Constructs a new input state.
/// </summary>
public InputHelper(ScreenManager manager)
{
_currentKeyboardState = new KeyboardState();
_currentGamePadState = new GamePadState();
_currentMouseState = new MouseState();
_currentVirtualState = new GamePadState();
_lastKeyboardState = new KeyboardState();
_lastGamePadState = new GamePadState();
_lastMouseState = new MouseState();
_lastVirtualState = new GamePadState();
_manager = manager;
_cursorIsVisible = false;
_cursorMoved = false;
#if WINDOWS_PHONE
_cursorIsValid = false;
#else
_cursorIsValid = true;
#endif
_cursor = Vector2.Zero;
_handleVirtualStick = false;
}
public GamePadState GamePadState
{
get { return _currentGamePadState; }
}
public KeyboardState KeyboardState
{
get { return _currentKeyboardState; }
}
public MouseState MouseState
{
get { return _currentMouseState; }
}
public GamePadState VirtualState
{
get { return _currentVirtualState; }
}
public GamePadState PreviousGamePadState
{
get { return _lastGamePadState; }
}
public KeyboardState PreviousKeyboardState
{
get { return _lastKeyboardState; }
}
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()
{
_cursorSprite = new Sprite(_manager.Game.Content.Load<Texture2D>("Common/cursor"));
#if WINDOWS_PHONE
// virtual stick content
_phoneStick = new VirtualStick(_manager.Game.Content.Load<Texture2D>("Common/socket"),
_manager.Game.Content.Load<Texture2D>("Common/stick"), new Vector2(80f, 400f));
Texture2D temp = _manager.Game.Content.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;
}
/// <summary>
/// Reads the latest state of the keyboard and gamepad and mouse/touchpad.
/// </summary>
public void Update(GameTime gameTime)
{
_lastKeyboardState = _currentKeyboardState;
_lastGamePadState = _currentGamePadState;
_lastMouseState = _currentMouseState;
if (_handleVirtualStick)
{
_lastVirtualState = _currentVirtualState;
}
_currentKeyboardState = Keyboard.GetState();
_currentGamePadState = GamePad.GetState(PlayerIndex.One);
_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
}
_gestures.Clear();
while (TouchPanel.IsGestureAvailable)
{
_gestures.Add(TouchPanel.ReadGesture());
}
// Update cursor
Vector2 oldCursor = _cursor;
if (_currentGamePadState.IsConnected && _currentGamePadState.ThumbSticks.Left != Vector2.Zero)
{
Vector2 temp = _currentGamePadState.ThumbSticks.Left;
_cursor += temp * new Vector2(300f, -300f) * (float)gameTime.ElapsedGameTime.TotalSeconds;
Mouse.SetPosition((int)_cursor.X, (int)_cursor.Y);
}
else
{
_cursor.X = _currentMouseState.X;
_cursor.Y = _currentMouseState.Y;
}
_cursor.X = MathHelper.Clamp(_cursor.X, 0f, _viewport.Width);
_cursor.Y = MathHelper.Clamp(_cursor.Y, 0f, _viewport.Height);
if (_cursorIsValid && oldCursor != _cursor)
{
_cursorMoved = true;
}
else
{
_cursorMoved = false;
}
#if WINDOWS
if (_viewport.Bounds.Contains(_currentMouseState.X, _currentMouseState.Y))
{
_cursorIsValid = true;
}
else
{
_cursorIsValid = false;
}
#elif WINDOWS_PHONE
if (_currentMouseState.LeftButton == ButtonState.Pressed)
{
_cursorIsValid = true;
}
else
{
_cursorIsValid = false;
}
#endif
}
public void Draw()
{
if (_cursorIsVisible && _cursorIsValid)
{
_manager.SpriteBatch.Begin();
_manager.SpriteBatch.Draw(_cursorSprite.Texture, _cursor, null, Color.White, 0f, _cursorSprite.Origin, 1f, SpriteEffects.None, 0f);
_manager.SpriteBatch.End();
}
#if WINDOWS_PHONE
if (_handleVirtualStick)
{
_manager.SpriteBatch.Begin();
_phoneA.Draw(_manager.SpriteBatch);
_phoneB.Draw(_manager.SpriteBatch);
_phoneStick.Draw(_manager.SpriteBatch);
_manager.SpriteBatch.End();
}
#endif
}
private GamePadState HandleVirtualStickWin()
{
Vector2 _leftStick = Vector2.Zero;
List<Buttons> _buttons = new List<Buttons>();
if (_currentKeyboardState.IsKeyDown(Keys.A))
{
_leftStick.X -= 1f;
}
if (_currentKeyboardState.IsKeyDown(Keys.S))
{
_leftStick.Y -= 1f;
}
if (_currentKeyboardState.IsKeyDown(Keys.D))
{
_leftStick.X += 1f;
}
if (_currentKeyboardState.IsKeyDown(Keys.W))
{
_leftStick.Y += 1f;
}
if (_currentKeyboardState.IsKeyDown(Keys.Space))
{
_buttons.Add(Buttons.A);
}
if (_currentKeyboardState.IsKeyDown(Keys.LeftControl))
{
_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>
/// Helper for checking if a key was newly pressed during this update.
/// </summary>
public bool IsNewKeyPress(Keys key)
{
return (_currentKeyboardState.IsKeyDown(key) &&
_lastKeyboardState.IsKeyUp(key));
}
public bool IsNewKeyRelease(Keys key)
{
return (_lastKeyboardState.IsKeyDown(key) &&
_currentKeyboardState.IsKeyUp(key));
}
public bool IsNewVirtualButtonPress(Buttons button)
{
return (_lastVirtualState.IsButtonUp(button) &&
_currentVirtualState.IsButtonDown(button));
}
public bool IsNewVirtualButtonRelease(Buttons button)
{
return (_lastVirtualState.IsButtonDown(button) &&
_currentVirtualState.IsButtonUp(button));
}
/// <summary>
/// Helper for checking if a button was newly pressed during this update.
/// </summary>
public bool IsNewButtonPress(Buttons button)
{
return (_currentGamePadState.IsButtonDown(button) &&
_lastGamePadState.IsButtonUp(button));
}
public bool IsNewButtonRelease(Buttons button)
{
return (_lastGamePadState.IsButtonDown(button) &&
_currentGamePadState.IsButtonUp(button));
}
/// <summary>
/// Helper for checking if a mouse button was newly pressed during this update.
/// </summary>
public bool IsNewMouseButtonPress(MouseButtons button)
{
switch (button)
{
case MouseButtons.LeftButton:
return (_currentMouseState.LeftButton == ButtonState.Pressed &&
_lastMouseState.LeftButton == ButtonState.Released);
case MouseButtons.RightButton:
return (_currentMouseState.RightButton == ButtonState.Pressed &&
_lastMouseState.RightButton == ButtonState.Released);
case MouseButtons.MiddleButton:
return (_currentMouseState.MiddleButton == ButtonState.Pressed &&
_lastMouseState.MiddleButton == ButtonState.Released);
case MouseButtons.ExtraButton1:
return (_currentMouseState.XButton1 == ButtonState.Pressed &&
_lastMouseState.XButton1 == ButtonState.Released);
case MouseButtons.ExtraButton2:
return (_currentMouseState.XButton2 == ButtonState.Pressed &&
_lastMouseState.XButton2 == ButtonState.Released);
default:
return false;
}
}
/// <summary>
/// Checks if the requested mouse button is released.
/// </summary>
/// <param name="button">The button.</param>
public bool IsNewMouseButtonRelease(MouseButtons button)
{
switch (button)
{
case MouseButtons.LeftButton:
return (_lastMouseState.LeftButton == ButtonState.Pressed &&
_currentMouseState.LeftButton == ButtonState.Released);
case MouseButtons.RightButton:
return (_lastMouseState.RightButton == ButtonState.Pressed &&
_currentMouseState.RightButton == ButtonState.Released);
case MouseButtons.MiddleButton:
return (_lastMouseState.MiddleButton == ButtonState.Pressed &&
_currentMouseState.MiddleButton == ButtonState.Released);
case MouseButtons.ExtraButton1:
return (_lastMouseState.XButton1 == ButtonState.Pressed &&
_currentMouseState.XButton1 == ButtonState.Released);
case MouseButtons.ExtraButton2:
return (_lastMouseState.XButton2 == ButtonState.Pressed &&
_currentMouseState.XButton2 == ButtonState.Released);
default:
return false;
}
}
/// <summary>
/// Checks for a "menu select" input action.
/// </summary>
public bool IsMenuSelect()
{
return IsNewKeyPress(Keys.Space) ||
IsNewKeyPress(Keys.Enter) ||
IsNewButtonPress(Buttons.A) ||
IsNewButtonPress(Buttons.Start) ||
IsNewMouseButtonPress(MouseButtons.LeftButton);
}
public bool IsMenuPressed()
{
return _currentKeyboardState.IsKeyDown(Keys.Space) ||
_currentKeyboardState.IsKeyDown(Keys.Enter) ||
_currentGamePadState.IsButtonDown(Buttons.A) ||
_currentGamePadState.IsButtonDown(Buttons.Start) ||
_currentMouseState.LeftButton == ButtonState.Pressed;
}
public bool IsMenuReleased()
{
return IsNewKeyRelease(Keys.Space) ||
IsNewKeyRelease(Keys.Enter) ||
IsNewButtonRelease(Buttons.A) ||
IsNewButtonRelease(Buttons.Start) ||
IsNewMouseButtonRelease(MouseButtons.LeftButton);
}
/// <summary>
/// Checks for a "menu cancel" input action.
/// </summary>
public bool IsMenuCancel()
{
return IsNewKeyPress(Keys.Escape) ||
IsNewButtonPress(Buttons.Back);
}
}
}