XNA 图形特效与文字显示 (转载)

public Game1()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";
    graphics.PreferredBackBufferHeight = 800;				//設定遊戲視窗的高度為800
    graphics.PreferredBackBufferWidth = 480;				//設定遊戲視窗的寬度為480
    TargetElapsedTime = TimeSpan.FromTicks(333333);
}

设定妥游戏窗口的高度和宽度之后请编辑 Game1 类别的 LoadContent 方法,负责加载游戏程序欲使用的资源,编辑好的 LoadContent 方法如下:

protected override void LoadContent()
{
    spriteBatch = new SpriteBatch(GraphicsDevice);
    Mario = Content.Load<Texture2D>("Mario");	  //從Content Pipeline專案載入欲顯示的圖案
MarioPosition = new Vector2(0, 0);            //設定圖案要顯示在遊戲視窗的最左上角
}

最后我们只要在 Game1 类别的 Draw 方法中呼叫 SpriteBatch 的 Draw 方法,传入适当的参数,就可以显示出各种特殊的效果,例如以下的 Draw 方法便会旋转、放大/缩小、水平/垂直翻转、改变图案色调、以及设定图案的透明度:

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);
    spriteBatch.Begin();			                      	//宣告批次繪圖動作開始

    spriteBatch.Draw(Mario, MarioPosition, Color.White);	//顯示未加上特殊效果的圖案
    spriteBatch.Draw(Mario, new Vector2(MarioPosition.X + Mario.Width*2, MarioPosition.Y 
+ Mario.Height), null, Color.White, MathHelper.ToRadians(180), new Vector2(0, 0), 1, SpriteEffects.None, 0);						//將圖案旋轉180度
    spriteBatch.Draw(Mario, new Vector2(MarioPosition.X + Mario.Width * 2, 0), null, 
Color.White, 0, new Vector2(0, 0), 1, 
SpriteEffects.FlipHorizontally, 0);						//將圖案水平翻轉

    spriteBatch.Draw(Mario, new Vector2(MarioPosition.X , MarioPosition.Y + Mario.Height), 
Color.Red);								//以紅色的色調顯示圖案
spriteBatch.Draw(Mario, new Vector2(MarioPosition.X + Mario.Width, MarioPosition.Y + 
Mario.Height), Color.Blue);					//以藍色的色調顯示圖案
    spriteBatch.Draw(Mario, new Vector2(MarioPosition.X + Mario.Width * 2, MarioPosition.Y 
+ Mario.Height), Color.Green);					//以綠色的色調顯示圖案

    spriteBatch.Draw(Mario, new Vector2(MarioPosition.X, MarioPosition.Y + 
Mario.Height*2), null, Color.White, 0, new Vector2(0, 0), 1, 
SpriteEffects.None, 0);						//以圖案原始大小顯示圖案
    spriteBatch.Draw(Mario, new Vector2(MarioPosition.X + Mario.Width, MarioPosition.Y + 
Mario.Height * 2), null, Color.White, 0, new Vector2(0, 0), 0.5f, SpriteEffects.None, 0);	//以原圖一半的大小顯示圖案
spriteBatch.Draw(Mario, new Vector2(MarioPosition.X + Mario.Width*1.5f, 
MarioPosition.Y + Mario.Height * 2), null, Color.White, 0, new Vector2(0, 0), 2, SpriteEffects.None, 0);						//以原圖兩倍的大小顯示圖案

    spriteBatch.Draw(Mario, new Vector2(MarioPosition.X, MarioPosition.Y + 
Mario.Height*4), null, new Color(255, 255, 255, 255), 0, new Vector2(0, 0), 1, SpriteEffects.None, 0);						    //以原始透明度顯示圖案
spriteBatch.Draw(Mario, new Vector2(MarioPosition.X + Mario.Width, MarioPosition.Y + 
Mario.Height * 4), null, new Color(255, 255, 255, 170), 0, new Vector2(0, 0), 1, SpriteEffects.None, 0);						 //以約2/3的透明度顯示圖案
spriteBatch.Draw(Mario, new Vector2(MarioPosition.X + Mario.Width*2, MarioPosition.Y 
+ Mario.Height * 4), null, new Color(255, 255, 255, 85), 0, new Vector2(0, 0), 1, SpriteEffects.None, 0);					//以約1/3的透明度顯示圖案

    spriteBatch.End();								    //宣告批次繪圖動作結束
base.Draw(gameTime);
}

做好之后请执行项目,您就会看到如图1的画面,看到传入不同的参数内容给 SpriteBatch 类别的 Draw 方法显示的内容的结果:

图1:传入不同的参数内容控制SpriteBatch类别的Draw方法显示的内容的结果

注:本文所使用的人物图案来源来自:http://www.emutalk.net/showthread.php?t=43273

[说明]

呼叫 SpriteBatch 类别的 Draw 方法执行旋转图案的时候而要传入的旋转角度的单位是弪度量,而不是惯用的度度量。以 XNA 为基础的游戏程序可以利用 MathHelper 类别的 ToRadians 方法指定的度度量角度转换成弪度量,再交给 SpriteBatch 类别的 Draw 方法执行旋转图案的动作。

MathHelper 类别是 XNA Framework 中提供高效能数学运算功能的类别,负责提供游戏执行时需要的数学运算。有关 MathHelper 类别常用的属性可以参考表 4 的说明:

表 4 :MathHelper 类别常用的属性
属性名称说明
E代表数学上的指数常数 e (亦称欧拉数 – Euler's Number )。
Log10E代表以 10 为基底的对数 e 。
Log2E代表以 2 为基底的对数 e 。
Pi代表圆周率(pi)。
PiOver2代表/2。
PiOver4代表/4。
TwoPi代表2。

MathHelper 类别常用的方法请参考表 5 的说明:

表 5:MathHelper 类别常用的方法
方法名称说明
Clamp限制数值必须介于指定的数值范围。
Distance计算两个数值之间的距离。
Hermite执行 Hermite Spline 内插法。
Lerp于两点之间执行线性内插。
Max取得两个数值中较大者的内容值。
Min取得两个数值中较小者的内容值。
SmoothStep利用 cubic 方程式计算两个数值间的内插值。
ToDegrees将弪度量转换成度度量。
ToRadians将度度量转换成弪度量。
WrapAngle限制角度必须介于π和-π之间。

[提示]

您只要善用 Game1 类别的 Update 方法,动态更新传递给 SpriteBatch 类别的 Draw 方法的参数内容值,就可以很容易地令所开发的游戏程序动态旋转图案、动态放大/缩小图案、或是动态令图案逐渐变成透明/不透明。

SpriteBatch 类别与文字输出支持

SpriteBatch 类别除了能够执行显示图案的功能以下,还能够协助游戏程序显示文字,当游戏程序需要显示菜单供用户选择,或是需要显示游戏的状态(包括分数和游戏的关卡)时,就会需要使用到 SpriteBatch 类别支持显示文字的功能。

游戏程序可以利用 SpriteBatch 类别的 DrawString 方法执行显示文字的动作,和 Draw 方法支持多种多载版本一样,SpriteBatch 类别支持的 DrawString 方法一共有以下 6 个不同的多载版本:

SpriteBatch.DrawString(spriteFont, text, position, color)

SpriteBatch.DrawString(spriteFont, text, position, color, rotation, origin, scale,

effects, layerDepth)

SpriteBatch.DrawString(spriteFont, text, position, color, rotation, origin,

scale, effects, layerDepth)

SpriteBatch.DrawString(spriteFont, text, position, color)

SpriteBatch.DrawString(spriteFont, text, position, color, rotation, origin,

scale, effects, layerDepth)

SpriteBatch.DrawString(spriteFont, text, position, color, rotation, origin,

scale, effects, layerDepth)

其需要用到的参数请参考表6的详细说明:

表 4 :SpriteBatch 类别的 DrawString 方法需要使用的参数
参数名称说明
spriteFont型态为 SpriteFont 类别的参数,负责记录欲输出的文字的定义。
text欲输出的文字,其型态可以是 String 类别或 StringBuilder 类别。
position指定欲输出的文字的左上角点坐标。
color负责控制欲输出的文字的色调的参数,传入 Color.White 表示不改变欲显示的文字的色调。
rotation依据输出的文字的圆心旋转 2 维输出的文字。
origin旋转文字时所依据的圆心。
scale文字放大/缩小的倍数。
effects设定成 SpriteEffects.FlipHorizontally 表示要水平翻转所显示的文字,设定成 SpriteEffects.FlipVertically 表示要垂直翻转所显示的文字。
layerDepth图层深度。0 代表前景层,1 代表背景层,可以搭配呼叫 SpriteBatch 类别的 Begin 方法传入的 SpriteSortMode 参数控制是否要对欲绘制的内容依 layerDepth 的内容值排序。

[提示]

呼叫 SpriteBatch 类别的 DrawString 方法需要的参数和 Draw 方法需要的参数几乎完全相同,所代表的意义和使用方式也都一样。

了解 SpriteBatch 类别的 DrawString 方法的基本功能之后,接下来我们就要为游戏程序加入显示文字的功能。

要显示文字,请先使用鼠标的右键点中 [Solution Explorer] 窗口中的 Content Pipeline 项目名称,再从出现的菜单选择 [Add | New Item] 功能,屏幕上就会出现如图 2 的画面,要求您选择欲新增的资源项目:

图 2:要求选择欲新增的资源项目的画面

请于中间窗口选择 [Sprite Font] 项目,于 [Name] 字段输入字型定义档案的名称,做好之后按下 [Add] 键,执行新增 SpriteFont 资源到 Content Pipeline 项目的动作,Visual Studio 2010 Express for Windows Phone 就会为 Content Pipeline 项目加入字型定义档案,其内容如下:


   
   
<?xml version="1.0" encoding="utf-8"?> <!-- This file contains an xml description of a font, and will be read by the XNA Framework Content Pipeline. Follow the comments to customize the appearance of the font in your game, and to change the characters which are available to draw with. --> <XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics"> <Asset Type="Graphics:FontDescription"> <!-- Modify this string to change the font that will be imported. --> <FontName>Segoe UI Mono</FontName> <!-- Size is a float value, measured in points. Modify this value to change the size of the font. --> <Size>14</Size> <!-- Spacing is a float value, measured in pixels. Modify this value to change the amount of spacing in between characters. --> <Spacing></Spacing> <!-- UseKerning controls the layout of the font. If this value is true, kerning information will be used when placing characters. --> <UseKerning>true</UseKerning> <!-- Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic", and "Bold, Italic", and are case sensitive. --> <Style>Regular</Style> <!-- If you uncomment this line, the default character will be substituted if you draw or measure text that contains characters which were not included in the font. --> <!-- <DefaultCharacter>*</DefaultCharacter> --> <!-- CharacterRegions control what letters are available in the font. Every character from Start to End will be built and made available for drawing. The default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin character set. The characters are ordered according to the Unicode standard. See the documentation for more information. --> <CharacterRegions> <CharacterRegion> <Start>&#32;</Start> <End>&#126;</End> </CharacterRegion> </CharacterRegions> </Asset> </XnaContent>

您可以利用 <FontName> 卷标指定欲显示的文字所使用的字型,利用 <Size> 卷标指定欲显示的文字的字号,利用 <Style> 卷标设定字型的样式,包括 Bold (粗体)和 Italic (斜体),利用 <CharacterRegion> 卷标指定欲显示的文字范围,包括利用 <Start> 卷标定义欲显示的字符中第一个字符的 Unicode ,利用 <End> 卷标定义欲显示的字符中最后一个字符的 Unicode 。例如以下就是一个 SpriteFont 字型定义文件的范例,指定欲使用大小为 18 的 Courier New 粗体字型,而且开头字符为 a,终止符为 z:


   
   
<?xml version="1.0" encoding="utf-8"?> <XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics"> <Asset Type="Graphics:FontDescription"> <FontName>Courier New</FontName> <Size>18</Size> <Spacing></Spacing> <UseKerning>true</UseKerning> <Style>Bold</Style> <CharacterRegions> <CharacterRegion> <Start>a</Start> <End>z</End> </CharacterRegion> </Asset> </XnaContent>

[注意]

请注意 SpriteFont 字型定义文件是一个内容大小写视为相异的 XML 文件,编辑字型定义的时候请特别注意大小写不要写错。除此之外,如果游戏程序需要显示汉字字符,因为汉字字符的 Unicode 内容值并不一定会连续,所以我们必须为每一个欲显示的中文字定义一个 <CharacterRegion> 段落,例如以下的字型定义,便会指定游戏程序可以显示 [中文]这两个中文字:


   
   
<CharacterRegions> <CharacterRegion> <Start>中</Start> <End>中</End> </CharacterRegion> <CharacterRegion> <Start>文</Start> <End>文</End> </CharacterRegion> </CharacterRegions>

定义好游戏程序欲显示的中文字型定义之后,就可以利用 SpriteFont 类别提供的功能管理游戏程序欲显示的字型。SpriteFont 类别常用的属性可以参考表 5 的说明:

表 5:SpriteFont 类别常用的属性
属性名称说明
Characters取得 SpriteFont 类别的对象管理的所有字符。
DefaultCharacter指定默认字符。如果 DefaultCharacter 属性的内容值设定为异于 null 的内容值,则当游戏程序欲显示 SpriteFont 字型定义文件中未定义的字符时,就会自动显示 DefaultCharacter 属性指定的字符。如果 DefaultCharacter 属性的内容值设定为 null,则当游戏程序欲显示 SpriteFont 字型定义文件中未定义的字符时,就会引发例外。

表 6 所示为 SpriteFont 类别常用的方法:

表 6:SpriteFont 类别常用的方法
方法名称说明
MeasureString传回 SpriteFont 字型定义文件定义的文字的高度与宽度。当游戏程序欲将文字显示在某个矩形的正中央的时候就需要用到这个方法。

准备好必要的字型定义文件之后,接下来我们就要为游戏程序加入显示文字的功能。

首先请于 Game1 类别加入以下的变量宣告,负责管理欲显示的文字,文字显示的位置,文字旋转的角度,以及旋转的圆心坐标:

SpriteFont GameFont;									//管理欲顯示的文字的變數
Vector2 FontPosition;								//管理文字顯示位置的變數
Vector2 RotateOrigin;						//管理旋轉文字依據的圓心座標的變數
float FontAngle = 0;									//管理文字旋轉角度的變數

然后于 Game1 类别的 LoadContent 方法加入以下的程序代码,负责加载欲显示的文字定义,计算欲显示的文字的大小,位置,以及旋转时的圆心坐标:

Viewport ViewPort = GraphicsDevice.Viewport;					//取得遊戲視窗的大小
GameFont = Content.Load<SpriteFont>("GameFont");	             //載入欲顯示的文字資源
Vector2 FontSize = GameFont.MeasureString("中文");			//計算欲顯示的文字的大小
FontPosition = new Vector2((ViewPort.Width - FontSize.X) / 2, 
(ViewPort.Height - FontSize.Y) / 2);  //設定文字要顯示在遊戲視窗的正中央
RotateOrigin = new Vector2(FontSize.X / 2, FontSize.Y / 2);//設定文字的中心為旋轉的圓心

[注意]

呼叫 Content 对象的 Load 方法加载 Content Pipeline 项目管理的字型资源时所传入的参数名称即扩展名为 .spritefont 的字型定义文件的主文件名,也就是图 2 所示加入字型资源的画面中于 [Name] 字段输入的文件名中的主档名。

加载妥游戏程序欲显示的文字资源之后,请将 Game1 类别的 Update 方法编辑成以下的样子,负责递增文字旋转的角度:

protected override void Update(GameTime gameTime)
{
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();
    if (FontAngle < 360)							//如果旋轉角度尚未到達360度
    {
        FontAngle += 1;									//遞增旋轉角度1度
    }
    // TODO: Add your update logic here
    base.Update(gameTime);
}

最后我们只要在 Game1 类别的 Draw 方法中呼叫 spriteBatch 对象的 End 方法之前加入以下的程序代码,负责显示字型定义文件中指定的中文字,并以文字中心点为圆心旋转所显示的文字

spriteBatch.DrawString(GameFont, "中文", FontPosition+RotateOrigin, Color.White, 
MathHelper.ToRadians(FontAngle), RotateOrigin, 1, SpriteEffects.None, 
0);		//呼叫SpriteBatch類別的DrawString方法顯示並依據指定的角度旋轉文字

做好之后请执行项目,您将会看到游戏程序显示的中文出现在游戏窗口的正中央,并以文字的中心点为圆心进行旋转的情形,如图 3 所示:

图 3:显示并旋转中文字的游戏程序执行的情形

[范例档案下载]

SpriteAndText.zip

原文链接:http://msdn.microsoft.com/zh-cn/windowsphone/gg570013.aspx

转载于:https://my.oschina.net/junwong/blog/40912

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值