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; } } } }
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。