測試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