测试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