SilverXna初体验:通用键盘输入设备
2011-12-13 20:29 独孤残云 阅读(1566) 评论(0) 编辑 收藏 举报继承上一节的设计思路,本节我们来补全SilverXna键盘输入设备的实现。
首先依然是常量和枚举定义:
InputTypes.cs
/*-------------------------------------
代码清单:InputTypes.cs
来自:http://www.cnblogs.com/kenkao
-------------------------------------*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace Microsoft.Xna.Framework.Input
{
// 鼠标设备动作
public enum MouseAction
{
None,
MouseLeftButtonDown,
MouseLeftButtonUp,
MouseRightButtonDown,
MouseRightButtonUp,
LostMouseCapture,
MouseEnter,
MouseLeave,
MouseMove,
MouseWheel
}
// 键盘设备动作
public enum KeyboardAction
{
None,
KeyDown,
KeyUp
}
// 鼠标键状态
public enum ButtonState
{
Released = 0,
Pressed = 1
}
// 键盘键状态
public enum KeyState
{
Up = 0,
Down = 1
}
// 鼠标设备委托定义
public delegate void MouseButtonHandler(MouseAction act, MouseButtonEventArgs e);
public delegate void MouseCommonHandler(MouseAction act, MouseEventArgs e);
public delegate void MouseWheelHandler(MouseAction act, MouseWheelEventArgs e);
// 键盘设备委托定义
public delegate void KeyboardHandler(KeyboardAction act, KeyEventArgs e);
}
代码清单:InputTypes.cs
来自:http://www.cnblogs.com/kenkao
-------------------------------------*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace Microsoft.Xna.Framework.Input
{
// 鼠标设备动作
public enum MouseAction
{
None,
MouseLeftButtonDown,
MouseLeftButtonUp,
MouseRightButtonDown,
MouseRightButtonUp,
LostMouseCapture,
MouseEnter,
MouseLeave,
MouseMove,
MouseWheel
}
// 键盘设备动作
public enum KeyboardAction
{
None,
KeyDown,
KeyUp
}
// 鼠标键状态
public enum ButtonState
{
Released = 0,
Pressed = 1
}
// 键盘键状态
public enum KeyState
{
Up = 0,
Down = 1
}
// 鼠标设备委托定义
public delegate void MouseButtonHandler(MouseAction act, MouseButtonEventArgs e);
public delegate void MouseCommonHandler(MouseAction act, MouseEventArgs e);
public delegate void MouseWheelHandler(MouseAction act, MouseWheelEventArgs e);
// 键盘设备委托定义
public delegate void KeyboardHandler(KeyboardAction act, KeyEventArgs e);
}
接下来是键盘设备状态的定义,思路仿前一节的MouseState,参看Xna内部的定义亦可:
KeyboardState.cs
/*-------------------------------------
代码清单:KeyboardState.cs
来自:http://www.cnblogs.com/kenkao
-------------------------------------*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace Microsoft.Xna.Framework.Input
{
/// <summary>
/// 键盘设备状态
/// </summary>
public class KeyboardState
{
// 键位状态缓冲数组
KeyState[] _KeyStateBuffer;
// 构造函数
public KeyboardState(KeyState[] KeyStateBuffer)
{
_KeyStateBuffer = KeyStateBuffer;
}
// 获得单键状态
public KeyState this[Key key]
{
get
{
return _KeyStateBuffer[(int)key];
}
}
// 检测单键是否按下
public bool IsKeyDown(Key key)
{
return _KeyStateBuffer[(int)key] == KeyState.Down;
}
// 检测单键是否弹起
public bool IsKeyUp(Key key)
{
return _KeyStateBuffer[(int)key] == KeyState.Up;
}
// 重载 != 运算符
public static bool operator !=(KeyboardState a, KeyboardState b)
{
return !(a == b);
}
// 重载 == 运算符
public static bool operator ==(KeyboardState a, KeyboardState b)
{
return a._KeyStateBuffer == b._KeyStateBuffer;
}
}
}
代码清单:KeyboardState.cs
来自:http://www.cnblogs.com/kenkao
-------------------------------------*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace Microsoft.Xna.Framework.Input
{
/// <summary>
/// 键盘设备状态
/// </summary>
public class KeyboardState
{
// 键位状态缓冲数组
KeyState[] _KeyStateBuffer;
// 构造函数
public KeyboardState(KeyState[] KeyStateBuffer)
{
_KeyStateBuffer = KeyStateBuffer;
}
// 获得单键状态
public KeyState this[Key key]
{
get
{
return _KeyStateBuffer[(int)key];
}
}
// 检测单键是否按下
public bool IsKeyDown(Key key)
{
return _KeyStateBuffer[(int)key] == KeyState.Down;
}
// 检测单键是否弹起
public bool IsKeyUp(Key key)
{
return _KeyStateBuffer[(int)key] == KeyState.Up;
}
// 重载 != 运算符
public static bool operator !=(KeyboardState a, KeyboardState b)
{
return !(a == b);
}
// 重载 == 运算符
public static bool operator ==(KeyboardState a, KeyboardState b)
{
return a._KeyStateBuffer == b._KeyStateBuffer;
}
}
}
之后我们收集Silverlight控件的键盘响应事件,还原键盘设备输入状态即可。
Silverlight控件通用的键盘事件只有键位按下与弹起两种,因此实现起来相对简单。我们只需侦听并存储256个键位全部的按下和弹起状态即可。
KeyboardInput.cs
/*-------------------------------------
代码清单:KeyboardInput.cs
来自:http://www.cnblogs.com/kenkao
-------------------------------------*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace Microsoft.Xna.Framework.Input
{
public class KeyboardInput
{
// 256个键位状态
static KeyState[] _KeyStateBuffer = new KeyState[256];
// 监听根容器
static UIElement _Handle;
static public UIElement Handle
{ get { return _Handle; } }
// 键盘事件定义
static public event KeyboardHandler KeyboardEvent;
// 初始化键盘输入设备
static public void InitDevice(UIElement handle)
{
_Handle = handle;
_Handle.KeyDown += new KeyEventHandler(_Handle_KeyDown);
_Handle.KeyUp += new KeyEventHandler(_Handle_KeyUp);
}
// 获得键盘设备状态
static public KeyboardState GetState()
{
return new KeyboardState((KeyState[])_KeyStateBuffer.Clone());
}
// 设备内置键位按下事件处理
static void _Handle_KeyDown(object sender, KeyEventArgs e)
{
// 重置键位状态
int KeyIndex = (int)e.Key;
_KeyStateBuffer[KeyIndex] = KeyState.Down;
// 支持外链键位按下事件
if (KeyboardEvent != null)
KeyboardEvent.Invoke(KeyboardAction.KeyDown, e);
}
// 设备内置键位弹起事件
static void _Handle_KeyUp(object sender, KeyEventArgs e)
{
// 重置键位状态
int KeyIndex = (int)e.Key;
_KeyStateBuffer[KeyIndex] = KeyState.Up;
// 支持外链键位弹起事件
if (KeyboardEvent != null)
KeyboardEvent.Invoke(KeyboardAction.KeyUp, e);
}
}
}
代码清单:KeyboardInput.cs
来自:http://www.cnblogs.com/kenkao
-------------------------------------*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace Microsoft.Xna.Framework.Input
{
public class KeyboardInput
{
// 256个键位状态
static KeyState[] _KeyStateBuffer = new KeyState[256];
// 监听根容器
static UIElement _Handle;
static public UIElement Handle
{ get { return _Handle; } }
// 键盘事件定义
static public event KeyboardHandler KeyboardEvent;
// 初始化键盘输入设备
static public void InitDevice(UIElement handle)
{
_Handle = handle;
_Handle.KeyDown += new KeyEventHandler(_Handle_KeyDown);
_Handle.KeyUp += new KeyEventHandler(_Handle_KeyUp);
}
// 获得键盘设备状态
static public KeyboardState GetState()
{
return new KeyboardState((KeyState[])_KeyStateBuffer.Clone());
}
// 设备内置键位按下事件处理
static void _Handle_KeyDown(object sender, KeyEventArgs e)
{
// 重置键位状态
int KeyIndex = (int)e.Key;
_KeyStateBuffer[KeyIndex] = KeyState.Down;
// 支持外链键位按下事件
if (KeyboardEvent != null)
KeyboardEvent.Invoke(KeyboardAction.KeyDown, e);
}
// 设备内置键位弹起事件
static void _Handle_KeyUp(object sender, KeyEventArgs e)
{
// 重置键位状态
int KeyIndex = (int)e.Key;
_KeyStateBuffer[KeyIndex] = KeyState.Up;
// 支持外链键位弹起事件
if (KeyboardEvent != null)
KeyboardEvent.Invoke(KeyboardAction.KeyUp, e);
}
}
}
思路上完全仿上一节的MouseInput。然后我们将Silverlight默认根容器捆绑给构建好的键盘输入设备。
/*-------------------------------------
代码清单:MainPage.xaml.cs
来自:http://www.cnblogs.com/kenkao
-------------------------------------*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace SilverXna
{
public partial class MainPage : UserControl
{
Game _Game;
public MainPage()
{
InitializeComponent();
_Game = new Game(_GameSurface);
// 初始化键盘、鼠标输入设备
KeyboardInput.InitDevice(this);
MouseInput.InitDevice(this);
}
}
}
代码清单:MainPage.xaml.cs
来自:http://www.cnblogs.com/kenkao
-------------------------------------*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace SilverXna
{
public partial class MainPage : UserControl
{
Game _Game;
public MainPage()
{
InitializeComponent();
_Game = new Game(_GameSurface);
// 初始化键盘、鼠标输入设备
KeyboardInput.InitDevice(this);
MouseInput.InitDevice(this);
}
}
}
最后是我们的主体代码:
Game.cs
/*-------------------------------------
代码清单:Game.cs
来自:http://www.cnblogs.com/kenkao
-------------------------------------*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.IO;
namespace SilverXna
{
public class Game : SilverGame
{
SpriteBatch _SpriteBatch;
Texture2D texture;
public Game(DrawingSurface GameSurface)
: base(GameSurface)
{ }
public override void Initialize()
{
base.Initialize();
}
public override void LoadContent()
{
_SpriteBatch = new SpriteBatch(this);
Stream imageStream = Content.OpenResourceStream("SilverXna","Content/SLXNA.png");
texture = Content.LoadTexture2D(imageStream);
base.LoadContent();
}
public override void UnloadContent()
{
base.UnloadContent();
}
Vector2 pos = new Vector2(100, 100);
public override void Update(TimeSpan DeltaTime, TimeSpan TotalTime)
{
// 获得鼠标设备状态
MouseState mouseState = MouseInput.GetState();
// 更新纹理位置到鼠标左键单击点
if (mouseState.LeftButton == ButtonState.Pressed)
{
pos = new Vector2((float)mouseState.X, (float)mouseState.Y);
}
// 获得键盘设备状态
KeyboardState keyboardState = KeyboardInput.GetState();
// 如果D键按下,则纹理向右移动一个像素
if (keyboardState.IsKeyDown(Key.D))
{
pos = new Vector2(pos.X+1, pos.Y);
}
base.Update(DeltaTime, TotalTime);
}
public override void Draw(TimeSpan DeltaTime, TimeSpan TotalTime)
{
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, new Color(100, 149, 237, 255), 1.0f, 0);
_SpriteBatch.Begin(BlendState.AlphaBlend);
_SpriteBatch.Draw(texture, pos, new Color(255, 255, 255, 255));
_SpriteBatch.End();
base.Draw(DeltaTime, TotalTime);
}
}
}
代码清单:Game.cs
来自:http://www.cnblogs.com/kenkao
-------------------------------------*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.IO;
namespace SilverXna
{
public class Game : SilverGame
{
SpriteBatch _SpriteBatch;
Texture2D texture;
public Game(DrawingSurface GameSurface)
: base(GameSurface)
{ }
public override void Initialize()
{
base.Initialize();
}
public override void LoadContent()
{
_SpriteBatch = new SpriteBatch(this);
Stream imageStream = Content.OpenResourceStream("SilverXna","Content/SLXNA.png");
texture = Content.LoadTexture2D(imageStream);
base.LoadContent();
}
public override void UnloadContent()
{
base.UnloadContent();
}
Vector2 pos = new Vector2(100, 100);
public override void Update(TimeSpan DeltaTime, TimeSpan TotalTime)
{
// 获得鼠标设备状态
MouseState mouseState = MouseInput.GetState();
// 更新纹理位置到鼠标左键单击点
if (mouseState.LeftButton == ButtonState.Pressed)
{
pos = new Vector2((float)mouseState.X, (float)mouseState.Y);
}
// 获得键盘设备状态
KeyboardState keyboardState = KeyboardInput.GetState();
// 如果D键按下,则纹理向右移动一个像素
if (keyboardState.IsKeyDown(Key.D))
{
pos = new Vector2(pos.X+1, pos.Y);
}
base.Update(DeltaTime, TotalTime);
}
public override void Draw(TimeSpan DeltaTime, TimeSpan TotalTime)
{
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, new Color(100, 149, 237, 255), 1.0f, 0);
_SpriteBatch.Begin(BlendState.AlphaBlend);
_SpriteBatch.Draw(texture, pos, new Color(255, 255, 255, 255));
_SpriteBatch.End();
base.Draw(DeltaTime, TotalTime);
}
}
}
D键按下时,纹理会缓慢右移。当然,如果大家高兴的话,还可以自行实现W、A、S键的位移效果。
以上两节没有太多的难点,但却充当着重要的基础作用,建议大家自行理解并掌握。
以上,谢谢 ^ ^