#region File Description //----------------------------------------------------------------------------- // InputComponent.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; #endregion namespace RobotGameData.Input { #region Input Key enum /// /// Buttons of an Xbox 360 Controller /// public enum ControlPad { None = 0, Start, Back, A, B, X, Y, LeftShoulder, LeftStick, LeftTrigger, LeftThumbStickUp, LeftThumbStickDown, LeftThumbStickLeft, LeftThumbStickRight, RightShoulder, RightStick, RightTrigger, RightThumbStickUp, RightThumbStickDown, RightThumbStickLeft, RightThumbStickRight, LeftPad, RightPad, UpPad, DownPad, Count } /// /// Triggers of the Xbox360 Controller /// public enum Trigger { Left = 0, Right = 1, Count } #endregion /// /// It receives inputs from users, depending on their devices. /// It supports a keyboard and an Xbox 360 Controller devices and /// recognizes the input device’s key press state, key release state, /// and key stroke state. /// public class InputComponent { #region Fields private PlayerIndex playerIndex; private KeyboardState keyboardState; private KeyboardState oldKeyboardState; private KeyboardState emptyKeyboardState; private GamePadState gamePadState; private GamePadState oldGamePadState; private GamePadState emptyGamePadState; private float[] triggers = new float[(int) Trigger.Count]; private float[] oldTriggers = new float[(int)Trigger.Count]; private Vector2[] thumbStick = new Vector2[(int)Trigger.Count]; private Vector2[] oldThumbStick = new Vector2[(int)Trigger.Count]; private float[] vibrationAmount = new float[(int)Trigger.Count]; private TimeSpan vibrationDurationAccTime = TimeSpan.Zero; private TimeSpan vibrationDuration = TimeSpan.Zero; #endregion #region Properties public PlayerIndex PlayerIndex { get { return playerIndex; } } public float[] Triggers { get { return triggers; } } public Vector2[] ThumbStick { get { return thumbStick; } } public float[] VibrationAmount { get { return vibrationAmount; } } public bool IsConnectedControlPad { get { return gamePadState.IsConnected; } } #endregion /// /// Constructor. /// /// player index public InputComponent(PlayerIndex idx) { playerIndex = idx; } /// /// Initialize members /// public void Initialize() { // Save the empty state emptyKeyboardState = Keyboard.GetState(); emptyGamePadState = GamePad.GetState(playerIndex); } /// /// Process vibration of an Xbox 360 Controller /// /// public void Update(GameTime gameTime) { // GamePad vibrate if (vibrationDurationAccTime < vibrationDuration) { vibrationDurationAccTime += gameTime.ElapsedGameTime; GamePad.SetVibration(PlayerIndex, VibrationAmount[(int)Trigger.Left], VibrationAmount[(int)Trigger.Right]); } else if (vibrationDurationAccTime >= vibrationDuration) { // Reset vibrationDurationAccTime = TimeSpan.Zero; vibrationDuration = TimeSpan.Zero; GamePad.SetVibration(PlayerIndex, 0.0f, 0.0f); } } /// /// It gets executed before the input processing. /// It stores the current input state. /// public void PreUpdate() { // Check keyboard state keyboardState = Keyboard.GetState(); // Check GamePad state gamePadState = GamePad.GetState(playerIndex); // Check GamePad Tiggers amount Triggers[(int)Trigger.Left] = gamePadState.Triggers.Left; Triggers[(int)Trigger.Right] = gamePadState.Triggers.Right; // Check GamePad ThumbStick amount thumbStick[(int)Trigger.Left] = gamePadState.ThumbSticks.Left; thumbStick[(int)Trigger.Right] = gamePadState.ThumbSticks.Right; } /// /// It gets executed after the input processing. /// It stores the current input state to compare at the next frame. /// public void PostUpdate() { // Store key state to old state. oldKeyboardState = keyboardState; oldGamePadState = gamePadState; oldTriggers[(int)Trigger.Left] = Triggers[(int)Trigger.Left]; oldTriggers[(int)Trigger.Right] = Triggers[(int)Trigger.Right]; oldThumbStick[(int)Trigger.Left] = thumbStick[(int)Trigger.Left]; oldThumbStick[(int)Trigger.Right] = thumbStick[(int)Trigger.Right]; } /// /// Reset the input state. /// public void Reset() { // all key state reset keyboardState = oldKeyboardState = emptyKeyboardState; gamePadState = oldGamePadState = emptyGamePadState; vibrationDurationAccTime = TimeSpan.Zero; vibrationDuration = TimeSpan.Zero; // Stop the vibration GamePad.SetVibration(PlayerIndex, 0.0f, 0.0f); } /// /// checks whether the specified button of a keyboard is pressed. /// /// input key public bool IsPressKey(Keys key) { return keyboardState.IsKeyDown(key); } /// /// checks whether the specified button of a keyboard is released. /// /// input key public bool IsReleaseKey(Keys key) { return keyboardState.IsKeyUp(key); } /// /// checks whether the specified button of a keyboard is pressed once /// for this frame. /// /// input key public bool IsStrokeKey(Keys key) { // check stroke keyboard keys return (!oldKeyboardState.IsKeyDown(key) && IsPressKey(key)); } /// /// checks whether the specified button of an Xbox 360 controller is pressed. /// /// Button of the Xbox 360 controller public bool IsPressControlPad(ControlPad pad) { return IsControlPadState(gamePadState, pad, ButtonState.Pressed); } /// /// checks whether the specified button of an Xbox 360 controller is released. /// /// Button of the Xbox 360 controller public bool IsReleaseControlPad(ControlPad pad) { return IsControlPadState(gamePadState, pad, ButtonState.Released); } /// /// checks whether the specified button of an Xbox 360 controller /// is pressed once for this frame. /// /// Button of the Xbox 360 controller public bool IsStrokeControlPad(ControlPad pad) { switch (pad) { case ControlPad.LeftThumbStickUp: return IsStrokeThumbStickUp(Trigger.Left); case ControlPad.LeftThumbStickDown: return IsStrokeThumbStickDown(Trigger.Left); case ControlPad.LeftThumbStickLeft: return IsStrokeThumbStickLeft(Trigger.Left); case ControlPad.LeftThumbStickRight: return IsStrokeThumbStickRight(Trigger.Left); case ControlPad.RightThumbStickUp: return IsStrokeThumbStickUp(Trigger.Right); case ControlPad.RightThumbStickDown: return IsStrokeThumbStickDown(Trigger.Right); case ControlPad.RightThumbStickLeft: return IsStrokeThumbStickLeft(Trigger.Right); case ControlPad.RightThumbStickRight: return IsStrokeThumbStickRight(Trigger.Right); case ControlPad.LeftTrigger: return IsStrokeTriggers(Trigger.Left); case ControlPad.RightTrigger: return IsStrokeTriggers(Trigger.Right); }; // check stroke GamePad buttons return (!IsControlPadState(oldGamePadState, pad, ButtonState.Pressed) && IsPressControlPad(pad)); } /// /// checks whether the specified trigger of an Xbox 360 controller /// is pressed once for this frame. /// /// Thumb stick of the Xbox 360 controller public bool IsStrokeControlPadTriggers(Trigger index) { return (Triggers[(int)index] > 0.0f && oldTriggers[(int)index] <= 0.0f); } public bool IsStrokeThumbStickUp(Trigger index) { return (ThumbStick[(int)index].Y > 0.0f && oldThumbStick[(int)index].Y <= 0.0f); } public bool IsStrokeThumbStickDown(Trigger index) { return (ThumbStick[(int)index].Y < 0.0f && oldThumbStick[(int)index].Y >= 0.0f); } public bool IsStrokeThumbStickLeft(Trigger index) { return (ThumbStick[(int)index].X < 0.0f && oldThumbStick[(int)index].X >= 0.0f); } public bool IsStrokeThumbStickRight(Trigger index) { return (ThumbStick[(int)index].X > 0.0f && oldThumbStick[(int)index].X <= 0.0f); } public bool IsStrokeTriggers(Trigger index) { return (Triggers[(int)index] > 0.0f && oldTriggers[(int)index] <= 0.0f); } /// /// Set the vibration of an Xbox 360 controller /// /// Vibration duration time /// Left vibration amount /// Right vibration amount public void SetGamePadVibration(float duration, float leftAmount, float rightAmount) { leftAmount = MathHelper.Clamp(leftAmount, 0.0f, 1.0f); rightAmount = MathHelper.Clamp(rightAmount, 0.0f, 1.0f); vibrationDuration = TimeSpan.FromSeconds(duration); vibrationAmount[(int)Trigger.Left] = leftAmount; vibrationAmount[(int)Trigger.Right] = rightAmount; } /// /// returns the number of which the trigger of an Xbox 360 controller /// has been pressed. /// /// Pressing amount public float GetGamePadTriggers( Trigger index) { return Triggers[(int)index]; } /// /// returns the value of the angle which the thumb stick of an /// Xbox 360 controller has been pressed. /// /// /// public Vector2 GetThumbStickAmount(Trigger index) { return ThumbStick[(int)index]; } /// /// compares the input state of the Xbox 360 controller. /// /// target input state /// Button of the Xbox 360 Controller /// target button state /// private bool IsControlPadState(GamePadState targetGamePadState, ControlPad pad, ButtonState state) { switch (pad) { case ControlPad.Start: return (targetGamePadState.Buttons.Start == state); case ControlPad.Back: return (targetGamePadState.Buttons.Back == state); case ControlPad.A: return (targetGamePadState.Buttons.A == state); case ControlPad.B: return (targetGamePadState.Buttons.B == state); case ControlPad.X: return (targetGamePadState.Buttons.X == state); case ControlPad.Y: return (targetGamePadState.Buttons.Y == state); case ControlPad.LeftShoulder: return (targetGamePadState.Buttons.LeftShoulder == state); case ControlPad.LeftStick: return (targetGamePadState.Buttons.LeftStick == state); case ControlPad.RightShoulder: return (targetGamePadState.Buttons.RightShoulder == state); case ControlPad.RightStick: return (targetGamePadState.Buttons.RightStick == state); case ControlPad.LeftPad: return (targetGamePadState.DPad.Left == state); case ControlPad.RightPad: return (targetGamePadState.DPad.Right == state); case ControlPad.UpPad: return (targetGamePadState.DPad.Up == state); case ControlPad.DownPad: return (targetGamePadState.DPad.Down == state); case ControlPad.LeftTrigger: { if (state == ButtonState.Pressed) return (GetGamePadTriggers(Trigger.Left) > 0.0f); else if (state == ButtonState.Released) return (GetGamePadTriggers(Trigger.Left) == 0.0f); return false; } case ControlPad.RightTrigger: { if (state == ButtonState.Pressed) return (GetGamePadTriggers(Trigger.Right) > 0.0f); else if (state == ButtonState.Released) return (GetGamePadTriggers(Trigger.Right) == 0.0f); return false; } case ControlPad.LeftThumbStickUp: { if (state == ButtonState.Pressed) return (GetThumbStickAmount(Trigger.Left).Y > 0.0f); else if (state == ButtonState.Released) return (GetThumbStickAmount(Trigger.Left).Y == 0.0f); return false; } case ControlPad.LeftThumbStickDown: { if (state == ButtonState.Pressed) return (GetThumbStickAmount(Trigger.Left).Y < 0.0f); else if (state == ButtonState.Released) return (GetThumbStickAmount(Trigger.Left).Y == 0.0f); return false; } case ControlPad.LeftThumbStickLeft: { if (state == ButtonState.Pressed) return (GetThumbStickAmount(Trigger.Left).X < 0.0f); else if (state == ButtonState.Released) return (GetThumbStickAmount(Trigger.Left).X == 0.0f); return false; } case ControlPad.LeftThumbStickRight: { if (state == ButtonState.Pressed) return (GetThumbStickAmount(Trigger.Left).X > 0.0f); else if (state == ButtonState.Released) return (GetThumbStickAmount(Trigger.Left).X == 0.0f); return false; } case ControlPad.RightThumbStickUp: { if (state == ButtonState.Pressed) return (GetThumbStickAmount(Trigger.Right).Y > 0.0f); else if (state == ButtonState.Released) return (GetThumbStickAmount(Trigger.Right).Y == 0.0f); return false; } case ControlPad.RightThumbStickDown: { if (state == ButtonState.Pressed) return (GetThumbStickAmount(Trigger.Right).Y < 0.0f); else if (state == ButtonState.Released) return (GetThumbStickAmount(Trigger.Right).Y == 0.0f); return false; } case ControlPad.RightThumbStickLeft: { if (state == ButtonState.Pressed) return (GetThumbStickAmount(Trigger.Right).X < 0.0f); else if (state == ButtonState.Released) return (GetThumbStickAmount(Trigger.Right).Y == 0.0f); return false; } case ControlPad.RightThumbStickRight: { if (state == ButtonState.Pressed) return (GetThumbStickAmount(Trigger.Right).X > 0.0f); else if (state == ButtonState.Released) return (GetThumbStickAmount(Trigger.Right).Y == 0.0f); return false; } default: return false; } } } }