Sliverlight3D——使用Content、Sprite和用户输入
本文介绍了如何使用Content项目加载2D纹理等素材、如何使用SpriteBatch绘制2D纹理、如何处理用户的键盘和鼠标输入。
幸好自己没有在Silverlight 5 Beta版推出后就开始研究它,那时你还得用命令行编译shader,而RC版中就可以使用XNA内置的BasicEffect等五个shader了,但素材的加载还需要通过IO文件流自己编写代码,在正式版中终于等到了对XNA中的Content项目的支持,终于可以使用自己熟悉的XNA开发流程编写Silverlight 3D程序了。
本来想从原始的Silverlight应用程序模板开始,这样能更好地理解代码,但是Silverlight主程序好像无法引用Content项目,而在XNA中,要添加对Content项目的引用,在主程序中会有一个Add Content Reference命令,你可以指定它使用的Content项目,但我不知道在Silverlight中如何做。
只能从Silverlight Toolkit中的Silverlight 3d Application模板生成了,看了一下项目的.csproj文件,好像添加了一些与Content项目相关的配置,我也不知道如何手动编写。
这个例子中我通过Content项目加载了一张2D纹理,然后使用SpriteBatch将这张纹理绘制在屏幕上,最后还添加了代码使用键盘移动这张纹理,点击鼠标左键这张纹理也会移动到光标所在的位置。
首先移除这个模板自动生成的几个类和代码:Cube.cs、Scene.cs、VertexPositionColorNormal.cs、CustomEffect.slfx,还有MainPage.xaml.cs中的一些代码,这个例子不会用到它们。
加载并绘制素材
要加载纹理,可以在Content项目上右击,在弹出的菜单中选取添加→现有项: 在随后的弹出的资源管理器中选取要添加的图片文件即可。
然后在MainPage.xaml.cs中添加以下代码:
namespace Silverlight3dApp { public partial class MainPage { GraphicsDevice graphicsDevice; // 图形设备 ContentManager contentManager; // ContentManager SpriteBatch spriteBatch; // 绘制2D纹理的SpriteBatch Texture2D texture; // 要绘制的纹理 Vector2 position = Vector2.Zero; // 纹理的2D屏幕坐标 public MainPage() { InitializeComponent(); } private void UserControl_Loaded(object sender, RoutedEventArgs e) { // 检查GPU是否开启硬件加速 if (GraphicsDeviceManager.Current.RenderMode != RenderMode.Hardware) { MessageBox.Show("请在Silverlight插件页面激活enableGPUAcceleration=true。", "警告", MessageBoxButton.OK); } } private void DrawingSurface_Loaded(object sender, RoutedEventArgs e) { graphicsDevice = GraphicsDeviceManager.Current.GraphicsDevice; // 初始化图形设备 // 初始化ContentManager // 注意:在Silverlight中,ContentManager的Root Directory必须设置为Content contentManager = new ContentManager(null, "Content"); // 使用ContentManager加载纹理 texture = contentManager.Load<Texture2D>("einstein"); // 初始化SpriteBatch spriteBatch = new SpriteBatch(graphicsDevice); } private void DrawingSurface_Draw(object sender, DrawEventArgs e) { graphicsDevice.Clear(Color.Black); // 绘制2D纹理 spriteBatch.Begin(0, BlendState.Opaque); spriteBatch.Draw(texture, position, Color.White); spriteBatch.End(); e.InvalidateSurface(); } } }
运行程序,在屏幕上的左上角就显示了一张图片。
用户输入
要处理用户的键盘和鼠标输入,首先需要注册提供鼠标和键盘事件的根控件,MouseState位置是相对于这个控件的左上角位置的。
因此需要在MainPage()方法中添加以下代码:
public MainPage() { InitializeComponent(); // 注册提供鼠标和键盘事件的根控件 Keyboard.RootControl = this; Mouse.RootControl = this; }
然后在DrawingSurface_Draw中添加处理用户输入的代码:
private void DrawingSurface_Draw(object sender, DrawEventArgs e) { // 处理用户输入 HandleInput(); … }
而HandleInput()方法的具体代码如下:
void HandleInput() { // 获取当前的键盘和鼠标状态 KeyboardState keyboardState = Keyboard.GetState(); MouseState mouseState = Mouse.GetState(); // 如果点击鼠标左键,则将图片的左上角移动到光标的位置 if (mouseState.LeftButton == ButtonState.Pressed) { position = new Vector2(mouseState.X, mouseState.Y); } // 按下键盘上下左右箭头移动图片 foreach (Key key in keyboardState.GetPressedKeys()) { switch (key) { case Key.Left: position.X -= 5; if (position.X <0) position.X = 0; break; case Key.Right: position.X += 5; if (position.X > 640 - 128) position.X = 640 - 128; break; case Key.Up: position.Y -= 5; if (position.Y < 0) position.Y = 0; break; case Key.Down: position.Y += 5; if (position.Y > 480 - 128) position.Y = 480 - 128; break; } } }
注意:Microsoft.Xna.Framework.Input.Keyboard与System.Windows.Input.Keyboard命名空间有冲突,你可以用全名,但更好的方法是给Microsoft.Xna.Framework.Input.Keyboard起个别名,因此在顶部using代码块中添加以下代码:
using Keyboard = Microsoft.Xna.Framework.Input.Keyboard;
通过以上代码,你就可以按下键盘上下左右箭头移动图片,如果点击鼠标左键,则将图片的左上角移动到光标的位置了。
文件下载(已下载 2426 次)
发布时间:2012/1/12 下午4:49:46 阅读次数:9110