XNA基础(02) —— 绘制基础

     在所有的图形引擎中,绘制都是最基础的部分,本文将介绍在XNA框架中与绘制相关的基础知识。

     在XNA中,我们使用SpriteBatch来进行绘制。首先,我们需要使用SpriteBatch来绘制什么了?是精灵Sprite,对。

     那么Sprite通过什么来表现了?是纹理,比如2D纹理Texture2D。嗯,你可以把纹理想象成Sprite的外表,比如我们制作的一幅精灵图片,就是一个纹理。

    我们要如何才能把一幅图片加载到我们的游戏中来作为一个Sprite的纹理了?这要通过素材管道Content Pipeline。所谓素材,包括我们游戏中要用到的图片、模型、声音等,比如一个纹理图片就是素材的一种。素材管道就很容易理解了,它可以把我们需要的素材导入到我们的游戏中,以XNA能够识别的正确的格式。而且,格式的识别与转换是在编译期完成的。

      在新建的XNA项目中,会有一个默认的Content文件夹,通常,我们会把所有的素材放在这个地方,并且根据素材的种类我们会在其下创建一些子文件夹,比如Image子文件夹用来存放所有的图片素材,Audio文件夹用来存放声音素材等。

      当一个物件别被识别为素材后,就会有一个唯一的资产名称AssetName来标记它,我们可以通过素材的属性页来查看素材的AssetName属性并修改它。

      下面我们可以用素材管理器ContentManager将一个素材导入到游戏中:

Texture2D texture;

texture = Content.Load<Texture2D>(@"Image\logo"); //在上文提到的LoadContent方法中调用

 

      很多时候,我们的图片需要是透明的,那么如何在SpriteBatch绘制的时候将图片绘制为透明了?有两种方法:要么图片具有透明的背景,要么在制作图片时将需要透明的部分设置为纯正的洋红色(255,0,255)。除此之外,还需要注意,SpriteBlendMode模式必须为AlphaBlend(这也是默认模式,稍后会提到),才能达到我们期望的透明效果。

      在进行渲染时,我们还需要注意层深度(Layer Depth)。所谓Layer Depth,指的是你需要将目标Sprite绘制在哪一个深度的层次。默认情况下,SpriteBatch会根据你调用的顺序来决定Layer Depth的相对值,比如,你先调用SpriteBatch绘制Sprite A,然后调用SpriteBatch在同一位置绘制Sprite B,那么,Sprite B就会把Sprite A挡住。如果我们依靠调用SpriteBatch绘制的顺序来决定Sprite的深度,那就太不灵活了,为此,调用SpriteBatch绘制方法时,你可以指定一个代表层次深度的参数(范围0~1)来指示SpriteBatch按照我们希望的顺序来绘制对象。

      有了上面的这些基础之后,我们可以详细讲解一下XNA中的渲染过程。每次渲染的过程都类似下面的模式:         

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            spriteBatch.Begin();

            spriteBatch.Draw();

            spriteBatch.End();

            base.Draw(gameTime);
        }

(1)GraphicsDevice.Clear()方法用于清除屏幕背景。

(2)SpriteBatch.Begin()方法用于通知显卡准备绘制场景。

(3)轮流调用SpriteBatch.Draw()绘制所有组件。

(4)SpriteBatch.End()方法用于告诉显卡绘制已经完成。

(5)最后,显卡显示绘制的结果。

     SpriteBatch.Begin()方法有一个接受参数的重载:

void Begin(SpriteBlendMode blendMode, SpriteSortMode sortMode, SaveStateMode stateMode, Matrix transformMatrix) ;

     SpriteBlendMode 参数决定了Sprite的颜色与背景颜色的混合模式,默认为AlphaBlend,我们刚才提到过。

     SpriteSortMode参数决定了Sprite的排序模型,即与前面的Layer Depth关联。

     SaveStateMode参数用于控制是否保存图形设备的状态。

     TransformMatrix参数用于控制旋转、缩放等。

     接下来我们看最重要的绘制Draw方法:

void Draw(Texture2D texture, Vector2 position, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth);

     第一个Texture2D参数,表示要绘制Sprite的纹理。

     第二个Vector2参数,表示要绘制的Sprite的左上角的位置在哪里 。

     第三个Rectangle参数,表示要绘制源纹理的哪一个区域,如果要绘制纹理的全部部分,则传null。

     第四个Color参数,表示绘制时所调制的颜色通道。

     第五个参数rotation,表示要旋转的角度。

     第六个参数origin,表示围绕哪个位置进行旋转。

     第七个参数scale,表示绘制时要缩放的比例。

     第八个参数effects,表示是否进行翻转。SpriteEffects.FlipHorizontally -- 水平翻转;SpriteEffects.FlipVertically -- 垂直翻转。

     最后一个参数layerDepth,就是我们前面说过的要在哪一个深度层次绘制对象。

 

     最后,要解释一下,为什么需要在每次Draw调用时,都先调用GraphicsDevice.Clear()方法清除屏幕然后再重新绘制所有物件了?这样性能不是很差吗?而且有时候我们可能只有极小的一部分需要重新绘制。

     假设我们每次只重新绘制变动的那一部分,那我们就需要一个复杂的管理器来追踪每一个部分的变动,这样我们才有可能知道要重绘哪一部分。你可以想象一下,这个追踪的过程是相当复杂的。而且还存在这样的情况,那就是当一个Sprite移动时,它后面原先被挡住的Sprite会露出来,而这个Sprite可能又会挡住另外一个Sptrite的一部分,这样一来就更加复杂了。所以,每次重绘整个屏幕并不是一个坏的idea。     

     今天就讲到这里,下一节我们将讲述与FrameRate相关的知识。 

 

上一篇:XNA基础(01) —— 游戏循环

时间: 2024-10-12 16:17:35

XNA基础(02) —— 绘制基础的相关文章

《JavaScript高效图形编程(修订版)》——6.7 画布绘制基础

6.7 画布绘制基础 下面的九节将讨论基本的画布绘图命令. 6.7.1 画布元素 在网页中插入画布元素和插入任何其他HTML元素没有什么不同. 如果你不指定任何宽度或高度属性,默认大小为300×150像素.可以但不推荐通过CSS(例如,宽度:50%)改变画布大小.输出有可能是被扭曲或被缩放的,这取决于浏览器的实现.但是,你可以用CSS设置边框.边距和背景颜色,虽然这绝不会影响绘制到画布内容本身.坐标系统默认左上角为原点(0,0),因此绘制在坐标(10,15)的图案将定位在从左往右第10像素,从上

Python基础02 基本数据类型

原文:Python基础02 基本数据类型 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢!   简单的数据类型以及赋值   变量不需要声明 Python的变量不需要声明,你可以直接输入: >>>a = 10 那么你的内存里就有了一个变量a, 它的值是10,它的类型是integer (整数). 在此之前你不需要做什么特别的声明,而数据类型是Python自动决定的. >>>print a >>&

《SolidWorks 2013中文版完全自学手册》——第 2 章 草图绘制基础 2.1 草图绘制的基本知识

第 2 章 草图绘制基础 SolidWorks的大部分特征是由二维草图绘制开始的,草图绘制在该软件使用中占有重要地位,本章将详细介绍草图的绘制与编辑方法. 草图一般是由点.线.圆弧.圆和抛物线等基本图形构成的封闭或不封闭的几何图形,是三维实体建模的基础.一个完整的草图包括几何形状.几何关系和尺寸标注3方面的信息.能否熟练掌握草图的绘制和编辑方法,决定了能否快速三维建模,以及能否提高工程设计的效率,能否灵活地把该软件应用到其他领域. 知识点 草图绘制的基本知识 草图绘制 草图编辑 尺寸标注 2.1

《SAP CRM管理与实施指南》一一第2章 SAP CRM基础数据与基础功能

第2章 SAP CRM基础数据与基础功能 基础数据也称主数据,是整个CRM系统的基础,是系统运行的基石,被多个模块共同使用.基础数据中有诸多信息对流程和功能起着决定性的控制作用,比如合作伙伴关系.角色.销售视图数据及服务类数据均在相关流程中体现和应用.而在诸多流程和应用中均会用到一些基础功能,如业务合作伙伴处理.业务事务处理.定价.日期管理.操作及文本等.本章介绍SAP CRM中常用的基础数据和基础功能.项目实施中,主数据有时未受到足够的重视,这会导致一些问题,比如应用后未达成理想的效果.使用不

需要牢记的JavaScript基础知识_基础知识

声明(Declarations) undefined值在布尔类型环境中会被当作false. 数值类型环境中undefined值会被转换为NaN. 对一个空变量求值时,空值 null 在数值类型环境中会被当作0来对待,而布尔类型环境中会被当作false JavaScript 变量感觉上是被"提升"或移到了所有函数和语句之前.提升后的变量将返回 undefined 值,所以即使在使用或引用某个变量之后存在声明和初始化操作,这个被提升的引用仍将得到 undefined 值. 由于存在变量声明

Javascript基础与面向对象基础~Javascript中的语句如何被执行,如何改变执行顺序

本讲主要是JS语言中的代码如何被解释执行的,这个问题其实和其它语言是一样的,程序执行顺序为"从上到下",当然如果代码中有分支,它的执行顺序可能有所改变,而这种支在程序设计中叫做"分支结构(条件结构)",再或者某个操作需要反复执行10次,这在程序设计中叫做"循环结构". 正常的程序结构 //普通的结构 var info = "hello world" console.log(info); 带有分支的程序结构 //IF条件结构 v

Javascript基础与面向对象基础~第一讲 啥叫编程,啥叫程序员

啥叫编程,啥叫程序员?这是一个有意思的问题,呵呵! 啥叫编程 编程其时很简单,就是把一些抽象的东西通过代码的方式表现出现,而代码我们通常叫它开发语言,我们使用开发语言完成某种功能的过程,叫做编程! 啥叫程序员 程序员是一种有思想,有干劲,有热情,有梦想,而又与常人在某些地方不同的人,网上有很多说法,也有很多定义,如程序员应该叫苦B程序员,程序员应该叫码农,程序员应该叫IT民工等等,但我并不这样认为,程序员是可以被人们尊敬的,他们绝对是对未来有着美好希望,对工作有着执着的追求,对周边需要帮助的人有

Javascript基础与面向对象基础~第五讲 Javascript中的方法,类中的方法

上一文章主要说的是JS中的类,有很多朋友回复了我的文章,在此很感谢大家,也对一些朋友提出的问题进行了回复,"类"这东西,只是一种思想,我们不应该把重点放在"某种语言是否提供类,或者是否实现了类",这是不重要的,重要的是面向对象中的类的思想! 今天主要说的是方法,JS中的方法也叫做函数function,它将一些有关系的代码组织在一起,形成一个整体,这类似于面向对象中的封装,你不需要了解方法的实现细节,你只要去调用它,了解方法的签名即可. 最简单的函数(方法): <

Javascript基础与面向对象基础~第四讲 Javascript中的类对象

今天来说JS中如何实现类(class),事实上本应该昨天晚上写的,可我失言了,在些说一声"抱歉"!JS中的类是JS面向对象的基础,也是我最拿手的东西,你写的代码能否提高一个层次,一般是从这点上看出来的. 占占对类的定义: 类是对现实中的事物的抽象,一个类一般由属性和方法构成,属性是一些固定的信息,而方法是类的某种行为,类往往用来抽象一些复杂的对象,类与类这间可以进行继承,一般通过JS的function实现,JS中的类对象是实现JS面向对象的基础. 占占对结构体的定义: 一个结构体也是对

XNA基础(02) 绘制基础

在所有的图形引擎中,绘制都是最基础的部分,本文将介绍在XNA框架中与绘制相关的基础知识. 在XNA中,我们使用SpriteBatch来进行绘制.首先,我们需要使用SpriteBatch来绘制什么了?是精灵 Sprite,对. 那么Sprite通过什么来表现了?是纹理,比如2D纹理Texture2D.嗯,你可以把纹理想象成Sprite的外 表,比如我们制作的一幅精灵图片,就是一个纹理. 我们要如何才能把一幅图片加载到我们的游戏中来作为一个Sprite的纹理了?这要通过素材管道 Content Pi