XNA游戏:各种输入测试

测试XNA游戏中键盘输入,触控输入,按钮输入

Game1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;

using InputHandlerDemo.Inputs;

namespace InputHandlerDemo
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        SpriteFont font;
        Texture2D square;
        string action = "";

        GameInput gameInput;//游戏输入管理类
        TouchIndicatorCollection touchIndicators;

        Rectangle JumpRectangle = new Rectangle(0, 0, 480, 100);
        Rectangle UpRectangle = new Rectangle(0, 150, 480, 100);
        Rectangle PauseRectangle = new Rectangle(0, 500, 200, 100);
        //退出矩形
        Rectangle ExitRectangle = new Rectangle(220, 500, 200, 100);


        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            TargetElapsedTime = TimeSpan.FromTicks(333333);
            //设置高度和宽度
            graphics.PreferredBackBufferWidth = 480;
            graphics.PreferredBackBufferHeight = 800;  

        }

        protected override void Initialize()
        {
            //初始化游戏输入对象
            gameInput = new GameInput();
            touchIndicators = new TouchIndicatorCollection();

            AddInputs();

            base.Initialize();
        }
        /// <summary>
        /// 添加各种输入方式
        /// </summary>
        private void AddInputs()
        {
            //游戏按钮

            // Add keyboard, gamepad and touch inputs for Jump
            gameInput.AddKeyboardInput(Actions.Jump, Keys.A, true);//A键为跳
            gameInput.AddKeyboardInput(Actions.Jump, Keys.Space, false);//Space键为跳
            gameInput.AddTouchTapInput(Actions.Jump, JumpRectangle, false);//跳矩形区域为跳
            gameInput.AddTouchSlideInput(Actions.Jump, Input.Direction.Right, 5.0f);//右滑动为跳

            // Add keyboard, gamepad and touch inputs for Pause
            gameInput.AddGamePadInput(Actions.Pause, Buttons.Start, true);
            gameInput.AddKeyboardInput(Actions.Pause, Keys.P, true);
            gameInput.AddTouchTapInput(Actions.Pause, PauseRectangle, true);
            gameInput.AddAccelerometerInput(Actions.Pause,
                                            Input.Direction.Down,
                                            0.10f);

            // Add keyboard, gamepad and touch inputs for Up
            gameInput.AddGamePadInput(Actions.Up, Buttons.RightThumbstickUp, false);
            gameInput.AddGamePadInput(Actions.Up, Buttons.LeftThumbstickUp, false);
            gameInput.AddGamePadInput(Actions.Up, Buttons.DPadUp, false);
            gameInput.AddKeyboardInput(Actions.Up, Keys.Up, false);
            gameInput.AddKeyboardInput(Actions.Up, Keys.W, true);
            gameInput.AddTouchTapInput(Actions.Up, UpRectangle, true);
            gameInput.AddTouchSlideInput(Actions.Up, Input.Direction.Up, 5.0f);
            gameInput.AddAccelerometerInput(Actions.Up,
                                            Input.Direction.Up,
                                            0.10f);

            // Add keyboard, gamepad and touch inputs for Exit
            gameInput.AddGamePadInput(Actions.Exit, Buttons.Back, false);
            gameInput.AddKeyboardInput(Actions.Exit, Keys.Escape, false);
            gameInput.AddTouchTapInput(Actions.Exit, ExitRectangle, true);

            // Add some Gestures too, just to show them off?
            gameInput.AddTouchGestureInput(Actions.Jump,
                                           GestureType.VerticalDrag,
                                           JumpRectangle);
            gameInput.AddTouchGestureInput(Actions.Pause,
                                           GestureType.Hold,
                                           PauseRectangle);
        }

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            //加载内容
            font = Content.Load<SpriteFont>("Display");
            square = Content.Load<Texture2D>("Pixel");

        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            //根据输入类型更新游戏界面
            gameInput.BeginUpdate();

            //点击退出矩形,退出程序
            if (gameInput.IsPressed(Actions.Exit, PlayerIndex.One))
                this.Exit();

            if (gameInput.IsPressed(Actions.Jump, PlayerIndex.One))
                action = Actions.Jump;
  
            if (gameInput.IsPressed(Actions.Pause, PlayerIndex.One))
                action = Actions.Pause;

            if (gameInput.IsPressed(Actions.Up, PlayerIndex.One))
                action = Actions.Up;

            touchIndicators.Update(gameTime, Content);

            gameInput.EndUpdate();

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            //绘制游戏界面
            spriteBatch.Begin();

            spriteBatch.Draw(square, UpRectangle, Color.Blue);
            spriteBatch.DrawString(font,
                                   "Up",
                                   new Vector2(UpRectangle.Left + 20, UpRectangle.Top + 20),
                                   Color.Black);

            spriteBatch.Draw(square, JumpRectangle, Color.Yellow);
            spriteBatch.DrawString(font,
                                   "Jump",
                                   new Vector2(JumpRectangle.Left + 20, JumpRectangle.Top + 20),
                                   Color.Black);

            spriteBatch.Draw(square, PauseRectangle, Color.Green);
            spriteBatch.DrawString(font,
                                   "Pause",
                                   new Vector2(PauseRectangle.Left + 20, PauseRectangle.Top + 20),
                                   Color.Black);

            spriteBatch.Draw(square, ExitRectangle, Color.Red);
            spriteBatch.DrawString(font,
                                   "Exit",
                                   new Vector2(ExitRectangle.Left + 20, ExitRectangle.Top + 20),
                                   Color.Black);

            spriteBatch.DrawString(font, action, new Vector2(100, 350), Color.White);

            touchIndicators.Draw(spriteBatch);

            spriteBatch.End(); 

            base.Draw(gameTime);
        }
    }
}

Action.cs 游戏操作的类型

namespace InputHandlerDemo
{
    static class Actions
    {
        // 自定义的操作类型
        public const string Jump = "Jump";
        public const string Exit = "Exit";
        public const string Up = "Up";
        public const string Pause = "Pause";
    }
}

下面是输入的操作的封装类

GameInput.cs

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;


namespace InputHandlerDemo.Inputs
{
    /// <summary>
    /// 游戏输入管理类
    /// </summary>
    class GameInput
    {
        //输入类型字典
        Dictionary<string, Input> Inputs = new Dictionary<string, Input>();
        //获取输入类型
        public Input GetInput(string theAction)
        {
            //如果没有改类型的输入操作则添加一个
            if (Inputs.ContainsKey(theAction) == false)
            {
                Inputs.Add(theAction, new Input());
            }

            return Inputs[theAction];
        }

        public void BeginUpdate()
        {
            Input.BeginUpdate();
        }

        public void EndUpdate()
        {
            Input.EndUpdate();
        }

        public bool IsConnected(PlayerIndex thePlayer)
        {
            // If there never WAS a gamepad connected, just say the gamepad is STILL connected
            if (Input.GamepadConnectionState[thePlayer] == false)
                return true;

            return Input.IsConnected(thePlayer);
        }

        public bool IsPressed(string theAction)
        {
            if (!Inputs.ContainsKey(theAction))
            {
                return false;
            }

            return Inputs[theAction].IsPressed(PlayerIndex.One);
        }
        /// <summary>
        /// 判断单击的状态
        /// </summary>
        /// <param name="theAction">动作</param>
        /// <param name="thePlayer">玩家</param>
        /// <returns></returns>
        public bool IsPressed(string theAction, PlayerIndex thePlayer)
        {
            if (Inputs.ContainsKey(theAction) == false)
            {
                return false;
            }

            return Inputs[theAction].IsPressed(thePlayer);
        }

        public bool IsPressed(string theAction, PlayerIndex? thePlayer)
        {
            if (thePlayer == null)
            {
                PlayerIndex theReturnedControllingPlayer;
                return IsPressed(theAction, thePlayer, out theReturnedControllingPlayer);
            }

            return IsPressed(theAction, (PlayerIndex)thePlayer);
        }

        public bool IsPressed(string theAction, PlayerIndex? thePlayer, out PlayerIndex theControllingPlayer)
        {
            if (!Inputs.ContainsKey(theAction))
            {
                theControllingPlayer = PlayerIndex.One;
                return false;
            }

            if (thePlayer == null)
            {
                if (IsPressed(theAction, PlayerIndex.One))
                {
                    theControllingPlayer = PlayerIndex.One;
                    return true;
                }

                if (IsPressed(theAction, PlayerIndex.Two))
                {
                    theControllingPlayer = PlayerIndex.Two;
                    return true;
                }

                if (IsPressed(theAction, PlayerIndex.Three))
                {
                    theControllingPlayer = PlayerIndex.Three;
                    return true;
                }

                if (IsPressed(theAction, PlayerIndex.Four))
                {
                    theControllingPlayer = PlayerIndex.Four;
                    return true;
                }

                theControllingPlayer = PlayerIndex.One;
                return false;
            }

            theControllingPlayer = (PlayerIndex)thePlayer;
            return IsPressed(theAction, (PlayerIndex)thePlayer);
        }

        public void AddGamePadInput(string theAction, Buttons theButton,
                            bool isReleasedPreviously)
        {
            GetInput(theAction).AddGamepadInput(theButton, isReleasedPreviously);
        }

        public void AddTouchTapInput(string theAction, Rectangle theTouchArea,
                                     bool isReleasedPreviously)
        {
            GetInput(theAction).AddTouchTapInput(theTouchArea, isReleasedPreviously);
        }

        public void AddTouchSlideInput(string theAction, Input.Direction theDirection,
                                       float slideDistance)
        {
            GetInput(theAction).AddTouchSlideInput(theDirection, slideDistance);
        }

        public void AddKeyboardInput(string theAction, Keys theKey,
                                     bool isReleasedPreviously)
        {
            GetInput(theAction).AddKeyboardInput(theKey, isReleasedPreviously);
        }

        public void AddTouchGestureInput(string theAction, GestureType theGesture,
                                         Rectangle theRectangle)
        {
            GetInput(theAction).AddTouchGesture(theGesture, theRectangle);
        }

        public void AddAccelerometerInput(string theAction, Input.Direction theDirection,
                                          float tiltThreshold)
        {
            GetInput(theAction).AddAccelerometerInput(theDirection, tiltThreshold);
        }

        public Vector2 CurrentGesturePosition(string theAction)
        {
            return GetInput(theAction).CurrentGesturePosition();
        }

        public Vector2 CurrentGestureDelta(string theAction)
        {
            return GetInput(theAction).CurrentGestureDelta();
        }

        public Vector2 CurrentGesturePosition2(string theAction)
        {
            return GetInput(theAction).CurrentGesturePosition2();
        }

        public Vector2 CurrentGestureDelta2(string theAction)
        {
            return GetInput(theAction).CurrentGestureDelta2();
        }

        public Point CurrentTouchPoint(string theAction)
        {
            Vector2? currentPosition = GetInput(theAction).CurrentTouchPosition();
            if (currentPosition == null)
            {
                return new Point(-1, -1);
            }

            return new Point((int)currentPosition.Value.X, (int)currentPosition.Value.Y);
        }

        public Vector2 CurrentTouchPosition(string theAction)
        {
            Vector2? currentTouchPosition = GetInput(theAction).CurrentTouchPosition();
            if (currentTouchPosition == null)
            {
                return new Vector2(-1, -1);
            }

            return (Vector2)currentTouchPosition;
        }

        public float CurrentGestureScaleChange(string theAction)
        {
            // Scaling is dependent on the Pinch gesture. If no input has been setup for 
            // Pinch then just return 0 indicating no scale change has occurred.
            if (!GetInput(theAction).PinchGestureAvailable) return 0;

            // Get the current and previous locations of the two fingers
            Vector2 currentPositionFingerOne = CurrentGesturePosition(theAction);
            Vector2 previousPositionFingerOne
                = CurrentGesturePosition(theAction) - CurrentGestureDelta(theAction);
            Vector2 currentPositionFingerTwo = CurrentGesturePosition2(theAction);
            Vector2 previousPositionFingerTwo
                = CurrentGesturePosition2(theAction) - CurrentGestureDelta2(theAction);

            // Figure out the distance between the current and previous locations
            float currentDistance = Vector2.Distance(currentPositionFingerOne, currentPositionFingerTwo);
            float previousDistance
                = Vector2.Distance(previousPositionFingerOne, previousPositionFingerTwo);

            // Calculate the difference between the two and use that to alter the scale
            float scaleChange = (currentDistance - previousDistance) * .01f;
            return scaleChange;
        }

        public Vector3 CurrentAccelerometerReading(string theAction)
        {
            return GetInput(theAction).CurrentAccelerometerReading;
        }

    }
}

GestureDefinition.cs

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input.Touch;

namespace InputHandlerDemo.Inputs
{
    /// <summary>
    /// 手势定义
    /// </summary>
    class GestureDefinition
    {
        public GestureType Type;
        public Rectangle CollisionArea;
        public GestureSample Gesture;
        public Vector2 Delta;
        public Vector2 Delta2;
        public Vector2 Position;
        public Vector2 Position2;

        public GestureDefinition(GestureType theGestureType, Rectangle theGestureArea)
        {
            Gesture = new GestureSample(theGestureType, new TimeSpan(0),
                                        Vector2.Zero, Vector2.Zero,
                                        Vector2.Zero, Vector2.Zero);
            Type = theGestureType;
            CollisionArea = theGestureArea;
        }

        public GestureDefinition(GestureSample theGestureSample)
        {
            Gesture = theGestureSample;
            Type = theGestureSample.GestureType;
            CollisionArea = new Rectangle((int)theGestureSample.Position.X,
                                          (int)theGestureSample.Position.Y, 5, 5);

            Delta = theGestureSample.Delta;
            Delta2 = theGestureSample.Delta2;
            Position = theGestureSample.Position;
            Position2 = theGestureSample.Position2;
        }

    }
}

Input.cs

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework;
using Microsoft.Devices.Sensors;

namespace InputHandlerDemo.Inputs
{
    /// <summary>
    /// 输入操作类
    /// </summary>
    class Input
    {
        Dictionary<Keys, bool> keyboardInputs = new Dictionary<Keys, bool>();
        Dictionary<Buttons, bool> gamepadInputs = new Dictionary<Buttons, bool>();
        Dictionary<Rectangle, bool> touchTapInputs = new Dictionary<Rectangle, bool>();
        Dictionary<Direction, float> touchSlideInputs = new Dictionary<Direction, float>();
        Dictionary<int, GestureDefinition> gestureInputs = new Dictionary<int, GestureDefinition>();
        Dictionary<Direction, float> accelerometerInputs = new Dictionary<Direction, float>();

        static public Dictionary<PlayerIndex, GamePadState> CurrentGamePadState//当前玩家的控制状态
    = new Dictionary<PlayerIndex, GamePadState>();

        static public Dictionary<PlayerIndex, GamePadState> PreviousGamePadState//上一个玩家的控制状态
            = new Dictionary<PlayerIndex, GamePadState>();

        static public TouchCollection CurrentTouchLocationState;//当前的触控集合
        static public TouchCollection PreviousTouchLocationState;//上一个触控集合
        static public KeyboardState CurrentKeyboardState;//当前的键盘状态
        static public KeyboardState PreviousKeyboardState;//上一个键盘状态

        static public Dictionary<PlayerIndex, bool> GamepadConnectionState
    = new Dictionary<PlayerIndex, bool>();

        static private List<GestureDefinition> detectedGestures = new List<GestureDefinition>();


        static private Accelerometer accelerometerSensor;
        static private Vector3 currentAccelerometerReading;
        //方向
        public enum Direction
        {
            Up,
            Down,
            Left,
            Right
        }

        public Input()
        {
            if (CurrentGamePadState.Count == 0)
            {
                CurrentGamePadState.Add(PlayerIndex.One, GamePad.GetState(PlayerIndex.One));
                CurrentGamePadState.Add(PlayerIndex.Two, GamePad.GetState(PlayerIndex.Two));
                CurrentGamePadState.Add(PlayerIndex.Three, GamePad.GetState(PlayerIndex.Three));
                CurrentGamePadState.Add(PlayerIndex.Four, GamePad.GetState(PlayerIndex.Four));

                PreviousGamePadState.Add(PlayerIndex.One, GamePad.GetState(PlayerIndex.One));
                PreviousGamePadState.Add(PlayerIndex.Two, GamePad.GetState(PlayerIndex.Two));
                PreviousGamePadState.Add(PlayerIndex.Three, GamePad.GetState(PlayerIndex.Three));
                PreviousGamePadState.Add(PlayerIndex.Four, GamePad.GetState(PlayerIndex.Four));

                GamepadConnectionState.Add(PlayerIndex.One,
                    CurrentGamePadState[PlayerIndex.One].IsConnected);
                GamepadConnectionState.Add(PlayerIndex.Two,
                    CurrentGamePadState[PlayerIndex.Two].IsConnected);
                GamepadConnectionState.Add(PlayerIndex.Three,
                    CurrentGamePadState[PlayerIndex.Three].IsConnected);
                GamepadConnectionState.Add(PlayerIndex.Four,
                    CurrentGamePadState[PlayerIndex.Four].IsConnected);
            }
            //添加重力感应
            if (accelerometerSensor == null)
            {
                accelerometerSensor = new Accelerometer();
                accelerometerSensor.ReadingChanged
                    += new EventHandler<AccelerometerReadingEventArgs>(AccelerometerReadingChanged);
            }
        }
        /// <summary>
        /// 开始更新
        /// </summary>
        static public void BeginUpdate()
        {
            //PlayerIndex游戏玩家的索引,添加4个玩家
            CurrentGamePadState[PlayerIndex.One] = GamePad.GetState(PlayerIndex.One);
            CurrentGamePadState[PlayerIndex.Two] = GamePad.GetState(PlayerIndex.Two);
            CurrentGamePadState[PlayerIndex.Three] = GamePad.GetState(PlayerIndex.Three);
            CurrentGamePadState[PlayerIndex.Four] = GamePad.GetState(PlayerIndex.Four);
            //当前触摸的地方
            CurrentTouchLocationState = TouchPanel.GetState();
            //玩家1的状态
            CurrentKeyboardState = Keyboard.GetState(PlayerIndex.One);

            detectedGestures.Clear();
            while (TouchPanel.IsGestureAvailable)
            {
                GestureSample gesture = TouchPanel.ReadGesture();
                detectedGestures.Add(new GestureDefinition(gesture));
            }
        }
        /// <summary>
        /// 结束更新
        /// </summary>
        static public void EndUpdate()
        {
            //PlayerIndex游戏玩家的索引,日安家
            PreviousGamePadState[PlayerIndex.One] = CurrentGamePadState[PlayerIndex.One];
            PreviousGamePadState[PlayerIndex.Two] = CurrentGamePadState[PlayerIndex.Two];
            PreviousGamePadState[PlayerIndex.Three] = CurrentGamePadState[PlayerIndex.Three];
            PreviousGamePadState[PlayerIndex.Four] = CurrentGamePadState[PlayerIndex.Four];

            PreviousTouchLocationState = CurrentTouchLocationState;
            PreviousKeyboardState = CurrentKeyboardState;
        }

        private void AccelerometerReadingChanged(object sender, AccelerometerReadingEventArgs e)
        {
            currentAccelerometerReading.X = (float)e.X;
            currentAccelerometerReading.Y = (float)e.Y;
            currentAccelerometerReading.Z = (float)e.Z;
        }
        // 添加一个键盘输入
        public void AddKeyboardInput(Keys theKey, bool isReleasedPreviously)
        {
            if (keyboardInputs.ContainsKey(theKey))
            {
                keyboardInputs[theKey] = isReleasedPreviously;
                return;
            }
            keyboardInputs.Add(theKey, isReleasedPreviously);
        }
        //添加一个游戏按钮输入
        public void AddGamepadInput(Buttons theButton, bool isReleasedPreviously)
        {
            if (gamepadInputs.ContainsKey(theButton))
            {
                gamepadInputs[theButton] = isReleasedPreviously;
                return;
            }
            gamepadInputs.Add(theButton, isReleasedPreviously);
        }
        //添加一个手势单击输入
        public void AddTouchTapInput(Rectangle theTouchArea, bool isReleasedPreviously)
        {
            if (touchTapInputs.ContainsKey(theTouchArea))
            {
                touchTapInputs[theTouchArea] = isReleasedPreviously;
                return;
            }
            touchTapInputs.Add(theTouchArea, isReleasedPreviously);
        }
        //添加一个手势滑动输入
        public void AddTouchSlideInput(Direction theDirection, float slideDistance)
        {
            if (touchSlideInputs.ContainsKey(theDirection))
            {
                touchSlideInputs[theDirection] = slideDistance;
                return;
            }
            touchSlideInputs.Add(theDirection, slideDistance);
        }

        public bool PinchGestureAvailable = false;//手势是否可用
        public void AddTouchGesture(GestureType theGesture, Rectangle theTouchArea)
        {
            TouchPanel.EnabledGestures = theGesture | TouchPanel.EnabledGestures;
            gestureInputs.Add(gestureInputs.Count, new GestureDefinition(theGesture, theTouchArea));
            if (theGesture == GestureType.Pinch)
            {
                PinchGestureAvailable = true;
            }
        }

        static private bool isAccelerometerStarted = false;//重力加速是否可用
        public void AddAccelerometerInput(Direction direction, float tiltThreshold)
        {
            if (!isAccelerometerStarted)
            {
                try
                {
                    accelerometerSensor.Start();
                    isAccelerometerStarted = true;
                }
                catch (AccelerometerFailedException e)
                {
                    isAccelerometerStarted = false;
                    System.Diagnostics.Debug.WriteLine(e.Message);
                }
            }

            accelerometerInputs.Add(direction, tiltThreshold);
        }

        public void RemoveAccelerometerInputs()
        {
            if (isAccelerometerStarted)
            {
                try
                {
                    accelerometerSensor.Stop();
                    isAccelerometerStarted = false;
                }
                catch (AccelerometerFailedException e)
                {
                    // The sensor couldn't be stopped.
                    System.Diagnostics.Debug.WriteLine(e.Message);
                }
            }

            accelerometerInputs.Clear();
        }


        static public bool IsConnected(PlayerIndex thePlayerIndex)
        {
            return CurrentGamePadState[thePlayerIndex].IsConnected;
        }

        //是否选中玩家
        public bool IsPressed(PlayerIndex thePlayerIndex)
        {
            return IsPressed(thePlayerIndex, null);
        }

        public bool IsPressed(PlayerIndex thePlayerIndex, Rectangle? theCurrentObjectLocation)
        {
            if (IsKeyboardInputPressed())
            {
                return true;
            }

            if (IsGamepadInputPressed(thePlayerIndex))
            {
                return true;
            }

            if (IsTouchTapInputPressed())
            {
                return true;
            }

            if (IsTouchSlideInputPressed())
            {
                return true;
            }
            //点钟矩形区域
            if (IsGestureInputPressed(theCurrentObjectLocation))
            {
                return true;
            }

            return false;
        }

        private bool IsKeyboardInputPressed()
        {
            foreach (Keys aKey in keyboardInputs.Keys)
            {
                if (keyboardInputs[aKey]
                && CurrentKeyboardState.IsKeyDown(aKey)
                && !PreviousKeyboardState.IsKeyDown(aKey))
                {
                    return true;
                }
                else if (!keyboardInputs[aKey]
                && CurrentKeyboardState.IsKeyDown(aKey))
                {
                    return true;
                }
            }

            return false;
        }


        private bool IsGamepadInputPressed(PlayerIndex thePlayerIndex)
        {
            foreach (Buttons aButton in gamepadInputs.Keys)
            {
                if (gamepadInputs[aButton]
                && CurrentGamePadState[thePlayerIndex].IsButtonDown(aButton)
                && !PreviousGamePadState[thePlayerIndex].IsButtonDown(aButton))
                {
                    return true;
                }
                else if (!gamepadInputs[aButton]
                && CurrentGamePadState[thePlayerIndex].IsButtonDown(aButton))
                {
                    return true;
                }
            }

            return false;
        }

        private bool IsTouchTapInputPressed()
        {
            foreach (Rectangle touchArea in touchTapInputs.Keys)
            {
                if (touchTapInputs[touchArea]
                && touchArea.Intersects(CurrentTouchRectangle)
                && PreviousTouchPosition() == null)
                {
                    return true;
                }
                else if (!touchTapInputs[touchArea]
                && touchArea.Intersects(CurrentTouchRectangle))
                {
                    return true;
                }
            }

            return false;
        }

        private bool IsTouchSlideInputPressed()
        {
            foreach (Direction slideDirection in touchSlideInputs.Keys)
            {
                if (CurrentTouchPosition() != null && PreviousTouchPosition() != null)
                {
                    switch (slideDirection)
                    {
                        case Direction.Up:
                            {
                                if (CurrentTouchPosition().Value.Y + touchSlideInputs[slideDirection]
                                    < PreviousTouchPosition().Value.Y)
                                {
                                    return true;
                                }
                                break;
                            }

                        case Direction.Down:
                            {
                                if (CurrentTouchPosition().Value.Y - touchSlideInputs[slideDirection]
                                    > PreviousTouchPosition().Value.Y)
                                {
                                    return true;
                                }
                                break;
                            }

                        case Direction.Left:
                            {
                                if (CurrentTouchPosition().Value.X + touchSlideInputs[slideDirection]
                                    < PreviousTouchPosition().Value.X)
                                {
                                    return true;
                                }
                                break;
                            }

                        case Direction.Right:
                            {
                                if (CurrentTouchPosition().Value.X - touchSlideInputs[slideDirection]
                                    > PreviousTouchPosition().Value.X)
                                {
                                    return true;
                                }
                                break;
                            }
                    }
                }
            }

            return false;
        }

        private bool IsGestureInputPressed(Rectangle? theNewDetectionLocation)
        {
            currentGestureDefinition = null;

            if (detectedGestures.Count == 0) return false;

            // Check to see if any of the Gestures defined in the gestureInputs 
            // dictionary have been performed and detected.
            foreach (GestureDefinition userDefinedGesture in gestureInputs.Values)
            {
                foreach (GestureDefinition detectedGesture in detectedGestures)
                {
                    if (detectedGesture.Type == userDefinedGesture.Type)
                    {
                        // If a Rectangle area to check against has been passed in, then
                        // use that one, otherwise use the one originally defined
                        Rectangle areaToCheck = userDefinedGesture.CollisionArea;
                        if (theNewDetectionLocation != null)
                            areaToCheck = (Rectangle)theNewDetectionLocation;

                        // If the gesture detected was made in the area where users were
                        // interested in Input (they intersect), then a gesture input is
                        // considered detected.
                        if (detectedGesture.CollisionArea.Intersects(areaToCheck))
                        {
                            if (currentGestureDefinition == null)
                            {
                                currentGestureDefinition
                                    = new GestureDefinition(detectedGesture.Gesture);
                            }
                            else
                            {
                                // Some gestures like FreeDrag and Flick are registered many, 
                                // many times in a single Update frame. Since there is only 
                                // one variable to store the gesture info, you must add on
                                // any additional gesture values so there is a combination 
                                // of all the gesture information in currentGesture
                                currentGestureDefinition.Delta += detectedGesture.Delta;
                                currentGestureDefinition.Delta2 += detectedGesture.Delta2;
                                currentGestureDefinition.Position += detectedGesture.Position;
                                currentGestureDefinition.Position2 += detectedGesture.Position2;
                            }
                        }
                    }
                }
            }

            if (currentGestureDefinition != null) return true;

            return false;
        }

        private bool IsAccelerometerInputPressed()
        {
            foreach (KeyValuePair<Direction, float> input in accelerometerInputs)
            {
                switch (input.Key)
                {
                    case Direction.Up:
                        {
                            if (Math.Abs(currentAccelerometerReading.Y) > input.Value
                            && currentAccelerometerReading.Y < 0)
                            {
                                return true;
                            }
                            break;
                        }

                    case Direction.Down:
                        {
                            if (Math.Abs(currentAccelerometerReading.Y) > input.Value
                            && currentAccelerometerReading.Y > 0)
                            {
                                return true;
                            }
                            break;
                        }

                    case Direction.Left:
                        {
                            if (Math.Abs(currentAccelerometerReading.X) > input.Value
                            && currentAccelerometerReading.X < 0)
                            {
                                return true;
                            }
                            break;
                        }

                    case Direction.Right:
                        {
                            if (Math.Abs(currentAccelerometerReading.X) > input.Value
                            && currentAccelerometerReading.X > 0)
                            {
                                return true;
                            }
                            break;
                        }
                }
            }

            return false;
        }

        GestureDefinition currentGestureDefinition;
        public Vector2 CurrentGesturePosition()
        {
            if (currentGestureDefinition == null)
                return Vector2.Zero;

            return currentGestureDefinition.Position;
        }

        public Vector2 CurrentGesturePosition2()
        {
            if (currentGestureDefinition == null)
                return Vector2.Zero;

            return currentGestureDefinition.Position2;
        }

        public Vector2 CurrentGestureDelta()
        {
            if (currentGestureDefinition == null)
                return Vector2.Zero;

            return currentGestureDefinition.Delta;
        }

        public Vector2 CurrentGestureDelta2()
        {
            if (currentGestureDefinition == null)
                return Vector2.Zero;

            return currentGestureDefinition.Delta2;
        }


        public Vector2? CurrentTouchPosition()
        {
            foreach (TouchLocation location in CurrentTouchLocationState)
            {
                switch (location.State)
                {
                    case TouchLocationState.Pressed:
                        return location.Position;

                    case TouchLocationState.Moved:
                        return location.Position;
                }
            }

            return null;
        }

        private Vector2? PreviousTouchPosition()
        {
            foreach (TouchLocation location in PreviousTouchLocationState)
            {
                switch (location.State)
                {
                    case TouchLocationState.Pressed:
                        return location.Position;

                    case TouchLocationState.Moved:
                        return location.Position;
                }
            }

            return null;
        }


        private Rectangle CurrentTouchRectangle
        {
            get
            {
                Vector2? touchPosition = CurrentTouchPosition();
                if (touchPosition == null)
                    return Rectangle.Empty;

                return new Rectangle((int)touchPosition.Value.X - 5,
                                     (int)touchPosition.Value.Y - 5,
                                     10,
                                     10);
            }
        }


        public Vector3 CurrentAccelerometerReading
        {
            get
            {
                return currentAccelerometerReading;
            }
        }
    }
}

TouchIndicator.cs

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Content;


namespace InputHandlerDemo.Inputs
{
    /// <summary>
    /// 触控轨迹
    /// </summary>
    class TouchIndicator
    {
        int alphaValue = 255;
        public int TouchID;

        Texture2D touchCircleIndicatorTexture;
        Texture2D touchCrossHairIndicatorTexture;
        //轨迹集合
        List<Vector2> touchPositions = new List<Vector2>();
        /// <summary>
        /// 初始化触摸轨迹
        /// </summary>
        /// <param name="touchID"></param>
        /// <param name="content"></param>
        public TouchIndicator(int touchID, ContentManager content)
        {
            TouchID = touchID;

            touchCircleIndicatorTexture = content.Load<Texture2D>("Circle");
            touchCrossHairIndicatorTexture = content.Load<Texture2D>("Crosshair");
        }

        private Vector2? TouchPosition(TouchCollection touchLocationState)
        {
            TouchLocation touchLocation;
            if (touchLocationState.FindById(TouchID, out touchLocation))
            {
                return touchLocation.Position;
            }

            return null;
        }

        public void Update(TouchCollection touchLocationState)
        {
            Vector2? currentPosition = TouchPosition(touchLocationState);
            if (currentPosition == null)
            {
                if (touchPositions.Count > 0)
                {
                    alphaValue -= 20;
                    if (alphaValue <= 0)
                    {
                        touchPositions.Clear();
                        alphaValue = 255;
                    }
                }
            }
            else
            {
                if (alphaValue != 255)
                {
                    touchPositions.Clear();
                    alphaValue = 255;
                }

                touchPositions.Add((Vector2)currentPosition);
            }
        }
        /// <summary>
        /// 绘制界面
        /// </summary>
        /// <param name="batch"></param>
        public void Draw(SpriteBatch batch)
        {
            if (touchPositions.Count != 0)
            {
                Vector2 previousPosition = touchPositions[0];
                Vector2 offsetForCenteringTouchPosition = new Vector2(-25, 0);
                //绘制触摸的轨迹
                foreach (Vector2 aPosition in touchPositions)
                {
                    DrawLine(batch,
                             touchCircleIndicatorTexture,
                             touchCrossHairIndicatorTexture,
                             previousPosition + offsetForCenteringTouchPosition,
                             aPosition + offsetForCenteringTouchPosition,
                             new Color(0, 0, 255, alphaValue));

                    previousPosition = aPosition;
                }
            }
        }
        /// <summary>
        /// 画线
        /// </summary>
        /// <param name="batch"></param>
        /// <param name="lineTexture"></param>
        /// <param name="touchTexture"></param>
        /// <param name="startingPoint"></param>
        /// <param name="endingPoint"></param>
        /// <param name="lineColor"></param>
        void DrawLine(SpriteBatch batch, Texture2D lineTexture, Texture2D touchTexture,
              Vector2 startingPoint, Vector2 endingPoint, Color lineColor)
        {
            batch.Draw(touchTexture, startingPoint, lineColor);

            Vector2 difference = startingPoint - endingPoint;
            float lineLength = difference.Length() / 8;

            for (int i = 0; i < lineLength; i++)
            {
                batch.Draw(lineTexture, startingPoint, lineColor);
                startingPoint.X -= difference.X / lineLength;
                startingPoint.Y -= difference.Y / lineLength;
            }

            batch.Draw(touchTexture, endingPoint, lineColor);
        }
    }
}

TouchIndicatorCollection.cs

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Graphics;


namespace InputHandlerDemo.Inputs
{
    /// <summary>
    /// 触控轨迹集合
    /// </summary>
    class TouchIndicatorCollection
    {
        List<TouchIndicator> touchPositions = new List<TouchIndicator>();
        /// <summary>
        /// 更新游戏界面
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="content"></param>
        public void Update(GameTime gameTime, ContentManager content)
        {
            //在XNA中,TouchPanel可以向我们提供大量关于触控操作的信息  获取触控的集合
            TouchCollection currentTouchLocationState = TouchPanel.GetState();
            foreach (TouchLocation location in currentTouchLocationState)
            {//获取触控的位置
                bool isTouchIDAlreadyStored = false;
                foreach (TouchIndicator indicator in touchPositions)
                {
                    //如果触控的位置id存在则跳出整个循环
                    if (location.Id == indicator.TouchID)
                    {
                        isTouchIDAlreadyStored = true;
                        break;
                    }
                }

                if (!isTouchIDAlreadyStored)
                {
                    //加入一个触控的位置
                    TouchIndicator indicator = new TouchIndicator(location.Id, content);
                    touchPositions.Add(indicator);
                }
            }

            foreach (TouchIndicator indicator in touchPositions)
            {
                indicator.Update(currentTouchLocationState);
            }
        }

        public void Draw(SpriteBatch batch)
        {
            foreach (TouchIndicator indicator in touchPositions)
            {
                indicator.Draw(batch);
            }
        }
    }
}

 

posted on 2012-05-27 14:07  linzheng  阅读(1142)  评论(0编辑  收藏  举报

导航