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