天天看點

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,  

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

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

                                   "Jump",  

                                   new Vector2(JumpRectangle.Left + 20, JumpRectangle.Top + 20),  

            spriteBatch.Draw(square, PauseRectangle, Color.Green);  

                                   "Pause",  

                                   new Vector2(PauseRectangle.Left + 20, PauseRectangle.Top + 20),  

            spriteBatch.Draw(square, ExitRectangle, Color.Red);  

                                   "Exit",  

                                   new Vector2(ExitRectangle.Left + 20, ExitRectangle.Top + 20),  

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

            touchIndicators.Draw(spriteBatch);  

            spriteBatch.End();   

            base.Draw(gameTime);  

    }  

Action.cs 遊戲操作的類型

    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

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

        /// 判斷單擊的狀态  

        /// <param name="theAction">動作</param> 

        /// <param name="thePlayer">玩家</param> 

        /// <returns></returns> 

        public bool IsPressed(string theAction, PlayerIndex thePlayer)  

            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)  

                theControllingPlayer = PlayerIndex.One;  

                if (IsPressed(theAction, PlayerIndex.One))  

                {  

                    theControllingPlayer = PlayerIndex.One;  

                    return true;  

                }  

                if (IsPressed(theAction, PlayerIndex.Two))  

                    theControllingPlayer = PlayerIndex.Two;  

                if (IsPressed(theAction, PlayerIndex.Three))  

                    theControllingPlayer = PlayerIndex.Three;  

                if (IsPressed(theAction, PlayerIndex.Four))  

                    theControllingPlayer = PlayerIndex.Four;  

            theControllingPlayer = (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,  

            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

    /// 手勢定義  

    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;  

本文轉自linzheng 51CTO部落格,原文連結:http://blog.51cto.com/linzheng/1078366

繼續閱讀