暴米花 发表于 2006-12-21 12:33:00

[Clayman的专栏]中文XNA教程(二)—— Into the 2D World

<p><br/>我们会设置一个,专门发布Clayman写的XNA文章。</p><p>作者:Mike Fleishauer &amp; clayman<br/>本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。<br/>由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。<br/>Blog:http://blog.csdn.net/soilwork<br/>clayman_joe@yahoo.com.cn&nbsp; <br/>special thanks to Mike Fleishauer ^_^</p><p><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在第一章里,我们介绍了关于XNA的一些基础知识。但坦白的说,至今为止,我们还没有编写任何代码,而且只创建了一个单调的蓝色屏幕。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这一章,我们将尝试在屏幕上绘制一些东西,简单的2D图形。虽然2D游戏的时代已经渐渐远去,但即使你编写一个全3D的游戏,也不得不处理处理一些2D图形,比如简单的选项菜单、HUD(head up displays)等等。好了让我们开始把。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 打开上一章创建的项目,当然,你也可以创建一个新XNA项目。把解决方案改名为“Chapter2”,把工程和Game1.cs都重命名为“Sprite”,当弹出确认更改文件名的对话框时,点击确认。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 接下来,我们将在屏幕上绘制一张2D图片。但在这之前,需要介绍一点关于Sprite的概念。<br/>&nbsp;<br/><font color="#47b12c"><strong>什么是Sprite?</strong><br/>Sprite,也称为精灵,是一个直接绘制到屏幕上的2D图形。在传统的2D游戏中,你所看到的一切几乎都是sprite。但在3D游戏中,比如Halo,sprite逐渐演变为了用于增加3D图形视觉效果的纹理。在讨论3D图形时我们会详细讲解它。现在,简单的把sprite认为是2D图形就可以了。</font><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 继续,我们将把一些外部资源添加到工程中,为了方便管理,统一把资源放到一个单独的文件夹中。在Solution Explorer邮件点击Add-&gt;New Floder,命名为Graphics。接下来,邮件点击新创建的文件夹 Add-&gt;Existion Item….在弹出窗口中,导航到安装MC2源代码的目录下,在\Source\Data\Art中,选择mcl_splashscreen_planet_2.tga.文件。(当然,可以选择一张任何你喜欢的图片)。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 接下来,编写代码:<br/><font color="#0000ff">namespace Chapter2<br/>{<br/>&nbsp;&nbsp;&nbsp; partial class Sprites : Microsoft.Xna.Framework.Game<br/>&nbsp;&nbsp;&nbsp; {<br/></font><font color="#0000ff"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Microsoft.Xna.Framework.Graphics.SpriteBatch _sb;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Microsoft.Xna.Framework.Graphics.Texture2D _sprite;</strong><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Sprites()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();<br/></font><font color="#0000ff"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sb = new SpriteBatch(this.graphics.GraphicsDevice);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sprite = Texture2D.FromFile(this.graphics.GraphicsDevice, "../../Graphics/mcl_splashscreen_planet_2.tga");</strong><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected override void Update()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; float elapsed = (float)ElapsedTime.TotalSeconds;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UpdateComponents();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected override void Draw()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!graphics.EnsureDevice())<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br/></font><font color="#0000ff"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; graphics.GraphicsDevice.Clear(Color.Black);<br/></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; graphics.GraphicsDevice.BeginScene();<br/>&nbsp;<br/></font><font color="#0000ff"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sb.Begin();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sb.Draw(_sprite, new Vector2(0.0f, 0.0f), Color.Red);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sb.End();</strong><br/>&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DrawComponents();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; graphics.GraphicsDevice.EndScene();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; graphics.GraphicsDevice.Present();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>&nbsp;&nbsp;&nbsp; }<br/>}</font><br/>(加粗部分为我们添加的代码)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这些代码是什么意思呢?</p><p><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先,我们为Sprite类添加了两个全新的成员:<br/><strong><font color="#0000ff">private Microsoft.Xna.Framework.Graphics.SpriteBatch _sb;<br/>private Microsoft.Xna.Framework.Graphics.Texture2D _sprite;</font><br/></strong><br/>&nbsp;&nbsp;&nbsp;&nbsp; _sb是一个SpriteBatch对象。SpriteBatch对象代表了一批sprite,并且将在同样的状态设置下,绘制他们。大多数情况下,几乎所有的sprite都在同一个批次中。<br/>&nbsp;&nbsp;&nbsp;&nbsp; _sprite实际上是一张2D的纹理。它代表了一张将要绘制到屏幕上的图片。我们稍后将讨论不同类型的纹理,现在,只需知道2D纹理储存了在X和Y方向上,每个像素的颜色信息。也可以就把Texture2D认为是一张图片。XNA直接支持jpg,tga,dds,bmp,png格式的文件作为纹理。<br/><strong><font color="#0000ff">_sb = new SpriteBatch(this.graphics.GraphicsDevice);</font></strong><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 使用GraphicsDevice对象作为参数,实例化SpriteBatch。这里,参数的含义表示以后将用哪一个(一个程序中可以有多个GraphicsDevice)GraphicsDevice对象绘制_sb。<br/><strong><font color="#0000ff">_sprite = Texture2D.FromFile(this.graphics.GraphicsDevice, "../../Graphics/mcl_splashscreen_planet_2.tga");</font></strong><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这行代码把图片加载到内存中,实例化Texture2D对象。同样把当前的graphics device和图片的路径作为参数。如果在给定路径没有找到所要的图片,那么这个方法将抛出一个异常。<br/><strong><font color="#0000ff">graphics.GraphicsDevice.Clear(Color.Black);<br/></font></strong><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 把屏幕清理为黑色。上一节已经介绍过如何使用这个方法。现在我会告诉你为什么需要调用这个方法。如果把渲染比作绘图,那么显存就是我们的画板,通常把用于绘图的显存称为帧缓冲,如何不清理帧缓冲,那么上次在帧缓冲中绘制的图形仍然会保留在其中,并且这些数据处于一种不确定的状态。假设我们下次只在屏幕的左上角绘制图形,那么显示时,除了进行绘制的区域,其他部分可能会显示一些随机数据,相当于我们在一块绘制了大量图形的旧画板上绘图。因此,需要用Clear方法对帧缓冲进行初始化,填充为某个我们希望的背景颜色。<br/><strong><font color="#0000ff">_sb.Begin();<br/>_sb.Draw(_sprite, new Vector2(0.0f, 0.0f), Color.Red);<br/>_sb.End();</font></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 和之前提到的BeginScenne和EndScene一样,_sb.Begin和_sb.End方法告诉图形设备我们将要绘制sprite,所有绘制sprite的代码都必须在这两个方法之间。Draw方法是真正绘制图形的地方。这里的参数告诉显卡从坐标位置为(0,0)的地方开始绘制sprite。注意,绘制sprite的,所使用的是屏幕坐标系,这意味着屏幕中的每个像素对应一个(x,y),屏幕左上角的坐标总是(0,0),而右下的坐标则取决于屏幕分辨率,如果分辨率为1024 x 768那么右下的坐标就是(1024,768)。绘制sprite的位置应该在这两个坐标之间。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 运行程序看看吧:<br/><img src="http://www.xnacn.net/UpFile/UpAttachment/2006-9/2006917152212.jpg" alt=""/></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 虽然依旧很单调,但总是有了进步。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里你可能会有一些问题:为什么原来蓝色的天空,现在“燃烧”了起来。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注意看绘制sprite的代码,最后一个参数表示了绘制sprite时的色调。如果我们把它改为Color.White那么将获得和原图一样的效果。你看,使用XNA轻易就能实现一些特效。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 再绘制几个sprite<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在我们有4个相同大小的sprite了。你已经掌握了2D绘图的基础,足够完成一个2D游戏的背景渲染。再次提醒,所有的2D绘图操作都因该在Begin()和End()方法之间,而SpriteBatch方法调用又必须在BeginScene()和EndScene()方法之间。简单的说,应该按照以下顺序:<br/>--&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 开始渲染3D图形<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 渲染3D场景<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 开始渲染2D图形<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 渲染2D图片<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 结束2D渲染<br/>--&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 结束3D渲染<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 需要记住,2D图形的渲染和绘制他们的顺序有关系。在叠加区域,先渲染的图形总是会被后渲染的图形挡住,和在普通画布上绘图的原理一样。这也带领我们进入下一个话题,透明。<br/>&nbsp;<br/><strong>Transparent Blits</strong><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先,如果你要问我Blits是什么含意,那么我要告诉你,实际上你不必知道它是什么意思=.=。Blit的含义来自于BLT,表示Block Transfer,意思是把一个平面的一部分复制到另一个平面。好了,关键的问题就在于我们如何把图片中,不透明的部分复制到已有图片上。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为了渲染一个带透明效果的sprite,先来做一些辅助工作。首先,打开windows中的绘图板,任意绘制一个图形:<br/><br/></p><p><img src="http://www.xnacn.net/UpFile/UpAttachment/2006-9/2006917153426.jpg" border="0" alt=""/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 哈哈,我绘制图形的能力确实很惊人,不是吗^_^。接下来,再创建一张同样大小的图片。上一张图片是我们希望显示的部分,而现在这张图片则作为它的透明遮罩:<br/><br/><img src="http://www.xnacn.net/UpFile/UpAttachment/2006-9/200691715352.jpg" border="0" alt=""/></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一般情况下,遮罩里白色部分是不透明的,而黑色部分则表示透明区域。把两张图片分别保存为uglyStar.jpg和uglyStarMask.jpg。为了方便使用,把他们都添加到Grahics文件夹中。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在打开DirectX SDK中的DxTex.exe程序(它位于sdk安装路径的Utilities\Bin\x86件夹下)。选择File-&gt;New Texture…,在弹出的窗口中,把纹理尺寸设置为32x32,把Surface/Volume格式设置为Unsigned 32-bit: A8R8G8B8,如图所示:<br/><br/></p><p><img src="http://www.xnacn.net/UpFile/UpAttachment/2006-9/2006917153557.jpg" border="0" alt=""/></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 选择“Open onto this surface”,打开我们之前创建的红色星星uglyStar.jpg</p><p><img src="http://www.xnacn.net/UpFile/UpAttachment/2006-9/2006917153643.jpg" border="0" alt=""/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 选择“Open onto Alpha Channel of this Surface”,打开uglyStarMask.jpg</p><p><img src="http://www.xnacn.net/UpFile/UpAttachment/2006-9/2006917153733.jpg" border="0" alt=""/></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最后把文件保存为star.dds,并添加到Graphics文件夹。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 好了,现在有了一张带透明通道的图片,如何使用他呢。把它绘制到之前的天空上吧。添加如下代码:<br/>………………….<br/><font color="#0000ff">private Microsoft.Xna.Framework.Graphics.Texture2D _spriteStar;<br/>………………….<br/>public Sprites()<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp; ………………………<br/>&nbsp;&nbsp;&nbsp;&nbsp; _spriteStar = Texture2D.FromFile(graphics.GraphicsDevice, "../../Graphics/star.dds");<br/>}</font><br/><font color="#0000ff">protected override void Draw()<br/>{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp; ……………..<br/>&nbsp;&nbsp;&nbsp;&nbsp; graphics.GraphicsDevice.BeginScene();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp; _sb.Begin(SpriteBlendMode.AlphaBlend);<br/>&nbsp;&nbsp;&nbsp;&nbsp; _sb.Draw(_sprite, new Vector2(0.0f, 0.0f), Color.White);<br/>&nbsp;&nbsp;&nbsp;&nbsp; _sb.Draw(_sprite, new Vector2(_sprite.Width, 0.0f), Color.White);<br/>&nbsp;&nbsp;&nbsp;&nbsp; _sb.Draw(_sprite, new Vector2(_sprite.Width, _sprite.Height), Color.White);<br/>&nbsp;&nbsp;&nbsp;&nbsp; _sb.Draw(_sprite, new Vector2(0.0f, _sprite.Height), Color.White);<br/>&nbsp;&nbsp;&nbsp; _sb.Draw(_spriteStar, new Vector2(50.0f, 50.0f), Color.Yellow);<br/>&nbsp;&nbsp;&nbsp;&nbsp; _sb.End();</font><br/>&nbsp;……………………………<br/>}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 运行程序,你因该可以看到下图所示的结果:<br/></p><p><img src="http://www.xnacn.net/UpFile/UpAttachment/2006-9/2006917153839.jpg" border="0" alt=""/></p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注意到我们只显示了红色的部分没有?这都是透明遮罩的功劳。简要来说,你使用DirectX纹理工具,告诉了图片哪些部分需要渲染,哪些部分是透明的,注意这里使用了dds格式的文件,而不是bmp格式。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你因该对这行代码比较感兴趣:<br/><font color="#3300ff">_sb.Begin(SpriteBlendMode.AlphaBlend);</font><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用AlphaBlend作为SpriteBlendMode参数,会告诉XNA将要渲染一些带透明效果的图片。还记得我先前说过“大多数情况下,几乎所有的sprite都在同一个批次中”吗,好吧,我撒谎了-_-b。Alpha混合通常需要进行额外的计算,因此,应该把需要进行Alpha混合的sprite单独作为一个批次。一个批次用来绘制(静态)背景图片,另一个用来绘制带透明效果的前景物品。作为一条规则,你应该总是把需要alpha混合的sprite作为一个批次:<br/><font color="#0000ff">using System;<br/>using System.Collections.Generic;<br/>using Microsoft.Xna.Framework;<br/>using Microsoft.Xna.Framework.Audio;<br/>using Microsoft.Xna.Framework.Components;<br/>using Microsoft.Xna.Framework.Graphics;<br/>using Microsoft.Xna.Framework.Input;<br/>using Microsoft.Xna.Framework.Storage;<br/>&nbsp;<br/>namespace Chapter2<br/>{<br/>&nbsp;&nbsp;&nbsp; partial class Sprites : Microsoft.Xna.Framework.Game<br/>&nbsp;&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Microsoft.Xna.Framework.Graphics.SpriteBatch _sbBackground;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Microsoft.Xna.Framework.Graphics.SpriteBatch _sbForeground;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Microsoft.Xna.Framework.Graphics.Texture2D _sprite;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Microsoft.Xna.Framework.Graphics.Texture2D _spriteStar;<br/>&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Sprites()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.AllowUserResizing = true;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.IsMouseVisible = true;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sbBackground = new SpriteBatch(this.graphics.GraphicsDevice);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sbForeground = new SpriteBatch(this.graphics.GraphicsDevice);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sprite = Texture2D.FromFile(this.graphics.GraphicsDevice, "../../Graphics/mcl_splashscreen_planet_2.tga");<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _spriteStar = Texture2D.FromFile(graphics.GraphicsDevice, "../../Graphics/star.dds");<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected override void Update()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; float elapsed = (float)ElapsedTime.TotalSeconds;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UpdateComponents();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected override void Draw()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!graphics.EnsureDevice())<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; graphics.GraphicsDevice.Clear(Color.Black);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; graphics.GraphicsDevice.BeginScene();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sbBackground.Begin();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sbBackground.Draw(_sprite, new Vector2(0.0f, 0.0f), Color.White);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sbBackground.Draw(_sprite, new Vector2(_sprite.Width, 0.0f), Color.White);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sbBackground.Draw(_sprite, new Vector2(_sprite.Width, _sprite.Height), Color.White);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sbBackground.Draw(_sprite, new Vector2(0.0f, _sprite.Height), Color.White);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sbBackground.End();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sbForeground.Begin(SpriteBlendMode.AlphaBlend);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sbForeground.Draw(_spriteStar, new Vector2(50.0f, 50.0f), Color.White);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _sbForeground.End();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DrawComponents();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; graphics.GraphicsDevice.EndScene();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; graphics.GraphicsDevice.Present();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>&nbsp;&nbsp;&nbsp; }<br/>}</font><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 好了,第二部分到次结束,下一章,我们将让sprite动起来~~。</p>
页: [1]
查看完整版本: [Clayman的专栏]中文XNA教程(二)—— Into the 2D World