测试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); } } } }