天天看点

XNA游戏:各种输入测试 中

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.Collections.Generic;  

using Microsoft.Xna.Framework.Input;  

using Microsoft.Devices.Sensors;  

    /// 输入操作类  

    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));  

        /// 结束更新  

        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;  

            gamepadInputs.Add(theButton, isReleasedPreviously);  

        //添加一个手势单击输入  

        public void AddTouchTapInput(Rectangle theTouchArea, bool isReleasedPreviously)  

            if (touchTapInputs.ContainsKey(theTouchArea))  

                touchTapInputs[theTouchArea] = isReleasedPreviously;  

            touchTapInputs.Add(theTouchArea, isReleasedPreviously);  

        //添加一个手势滑动输入  

        public void AddTouchSlideInput(Direction theDirection, float slideDistance)  

            if (touchSlideInputs.ContainsKey(theDirection))  

                touchSlideInputs[theDirection] = slideDistance;  

            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)  

                    accelerometerSensor.Stop();  

                    // The sensor couldn't be stopped.  

            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))  

            if (IsTouchTapInputPressed())  

            if (IsTouchSlideInputPressed())  

            //点钟矩形区域  

            if (IsGestureInputPressed(theCurrentObjectLocation))  

            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))  

        private bool IsGamepadInputPressed(PlayerIndex thePlayerIndex)  

            foreach (Buttons aButton in gamepadInputs.Keys)  

                if (gamepadInputs[aButton]  

                && CurrentGamePadState[thePlayerIndex].IsButtonDown(aButton)  

                && !PreviousGamePadState[thePlayerIndex].IsButtonDown(aButton))  

                else if (!gamepadInputs[aButton]  

                && CurrentGamePadState[thePlayerIndex].IsButtonDown(aButton))  

        private bool IsTouchTapInputPressed()  

            foreach (Rectangle touchArea in touchTapInputs.Keys)  

                if (touchTapInputs[touchArea]  

                && touchArea.Intersects(CurrentTouchRectangle)  

                && PreviousTouchPosition() == null)  

                else if (!touchTapInputs[touchArea]  

                && touchArea.Intersects(CurrentTouchRectangle))  

        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)  

                        case Direction.Left:  

                                if (CurrentTouchPosition().Value.X + touchSlideInputs[slideDirection]  

                                    < PreviousTouchPosition().Value.X)  

                        case Direction.Right:  

                                if (CurrentTouchPosition().Value.X - touchSlideInputs[slideDirection]  

                                    > PreviousTouchPosition().Value.X)  

                    }  

        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;  

        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:  

                            && currentAccelerometerReading.Y > 0)  

                    case Direction.Left:  

                            if (Math.Abs(currentAccelerometerReading.X) > input.Value  

                            && currentAccelerometerReading.X < 0)  

                    case Direction.Right:  

                            && currentAccelerometerReading.X > 0)  

        GestureDefinition currentGestureDefinition;  

        public Vector2 CurrentGesturePosition()  

            if (currentGestureDefinition == null)  

                return Vector2.Zero;  

            return currentGestureDefinition.Position;  

        public Vector2 CurrentGesturePosition2()  

            return currentGestureDefinition.Position2;  

        public Vector2 CurrentGestureDelta()  

            return currentGestureDefinition.Delta;  

        public Vector2 CurrentGestureDelta2()  

            return currentGestureDefinition.Delta2;  

        public Vector2? CurrentTouchPosition()  

            foreach (TouchLocation location in CurrentTouchLocationState)  

                switch (location.State)  

                    case TouchLocationState.Pressed:  

                        return location.Position;  

                    case TouchLocationState.Moved:  

            return null;  

        private Vector2? PreviousTouchPosition()  

            foreach (TouchLocation location in PreviousTouchLocationState)  

        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  

                return currentAccelerometerReading;  

本文转自linzheng 51CTO博客,原文链接:http://blog.51cto.com/linzheng/1078372

继续阅读