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.KeyboardSystem.Windows.Input.Keyboard命名空间有冲突,你可以用全名,但更好的方法是给Microsoft.Xna.Framework.Input.Keyboard起个别名,因此在顶部using代码块中添加以下代码:

using Keyboard = Microsoft.Xna.Framework.Input.Keyboard; 

通过以上代码,你就可以按下键盘上下左右箭头移动图片,如果点击鼠标左键,则将图片的左上角移动到光标的位置了。

文件下载(已下载 2426 次)

发布时间:2012/1/12 下午4:49:46  阅读次数:9022

2006 - 2024,推荐分辨率 1024*768 以上,推荐浏览器 Chrome、Edge 等现代浏览器,截止 2021 年 12 月 5 日的访问次数:1872 万 9823 站长邮箱

沪 ICP 备 18037240 号-1

沪公网安备 31011002002865 号