3.7其他辅助类
Helpers
命名空间中还包括其他一些辅助类,大多数都像
RandomHelper
类一样简单,没有必要把它们都讲一遍,所以请你们自己看一下本章没有讲到的那些辅助类,如果想进一步了解它们可以使用其中的单元测试进行一些测试。
在介绍
Breakout
游戏之前,先简要地看看这样几个辅助类,它们在下面几章中会被反复地使用:
SpriteHelper
、
EnumHelper
和
ColorHelper
。
SpriteHelper类
上一章已经讲了很多渲染
sprite
的内容,当时为了配合单元测试而不得不使用一种简单的方式来处理
sprite
。很多时候需要把反复使用的有用代码放进可复用的类中,于是就产生了这样一个
SpriteHelper
类(如图
3-10
所示)。它提供了一个构造函数创建
SpriteHelper
实例,存储
texture
和
Graphic Rectangle
数据,还提供了一些渲染方法更方便地把
sprite
渲染输出到屏幕上,就像上一章中使用
SpriteToRender
类一样。
图3-10
这里的大多数方法的操作都不是很多,构造函数初始化变量的值,
Render
方法向
sprite
列表中添加
SpriteToRender
实例,
RenderCentered
方法在指定位置居中显示
sprite
,最后
DrawSprites
方法把所有
sprite
画到屏幕上。看一下其中的
DrawSprites
方法,它和前一章中的
DrawSprites
方法很像,不过有一些改进:
public
static
void
DrawSprites(
int
width,
int
height)
{
//
No need to render if we got no sprites this frame
if
(sprites.Count
==
0
)
return
;
//
Create sprite batch if we have not done it yet.
//
Use device from texture to create the sprite batch.
if
(spriteBatch
==
null
)
spriteBatch
=
new
SpriteBatch(sprites[
0
].texture.GraphicsDevice);
//
Start rendering sprites
spriteBatch.Begin(SpriteBlendMode.AlphaBlend,
SpriteSortMode.BackToFront, SaveStateMode.None);
//
Render all sprites
foreach
(SpriteToRender sprite
in
sprites)
spriteBatch.Draw(sprite.texture,
//
Rescale to fit resolution
new
Rectangle(
sprite.rect.X
*
width
/
1024
,
sprite.rect.Y
*
height
/
768
,
sprite.rect.Width
*
width
/
1024
,
sprite.rect.Height
*
height
/
768
),
sprite.sourceRect, sprite.color);
//
We are done, draw everything on screen with help of the end method.
spriteBatch.End();
//
Kill list of remembered sprites
sprites.Clear();
}
//
DrawSprites()
在调用该方法的时候,传递当前窗口分辨率的宽度和高度,并根据当前分辨率对所有
sprite
进行比例缩放,这对于支持
Xbox 360
的多分辨率非常重要。方法首先检查是否有东西要渲染,然后确保
SpriteBatch
类的静态实例(就是这里的
spriteBatch
变量)是否已被创建,调用
Begin
方法之后,在当前帧中遍历所有的
sprite
并重新调整它们的尺寸以适应当前屏幕的大小,最后当把所有
sprite
画到屏幕上之后再调用
End
方法。另外还要把
sprite
列表清空,为下一帧的渲染做准备。可以研究本章最后的
Breakout
游戏来看看这个类是如何工作的。
EnumHelper类
EnumHelper
类(如图
3-11
所示)对于遍历枚举项以及获取枚举值的个数等操作非常有用。在
Pong
和
Breakout
游戏中没有用到任何枚举类型,但下一章的游戏在遍历
block
类型的时候使用
Enum
类(
System.Enum
)有很大帮助。注意,
EnumHelper
类用到了
Enum
类的几个方法,这些方法在
.Net Compact Framework
中并没有被实现。为了避免编译错误,在
Xbox 360
项目中通常排除整个
EnumHelper
类,不过在
Windows
平台上可以使用它。
图3-11
单元测试的
TestGetAllEnumNames
方法如下所示,该测试说明了
GetAllEnumNames
方法是如何工作的,它借助
EnumHelper
类内部定义的
EnumEnumerator
辅助类来遍历所有的枚举值。
[Test]
public
void
TestGetAllEnumNames()
{
Assert.AreEqual(
"
Missions, Highscore, Credits, Help, Options, Exit, Back
"
,
EnumHelper.GetAllEnumNames(
typeof
(MenuButton)));
}
//
TestGetAllEnumNames()
GetAllEnumNames
方法则使用了之前讨论的
StringHelper
类中的
WriteArrayData
方法:
public
static
string
GetAllEnumNames(Type type)
{
return
StringHelper.WriteArrayData(GetEnumerator(type));
}
//
GetAllEnumNames(type)
ColorHelper类
ColorHelper
类如图
3-12
所示,原本它还有更多的方法,但
XNA
中新的
Color
类比托管
DirectX
中使用的
System.Drawings
中的
Color
类的功能更加强大,所以有很多方法就不再需要了,不过它还是包含了一些对颜色操作非常有用的方法。
图3-12
例如,
ColorHelper.Empty
字段可以用来把
shader
效果参数设置为空值——
0,0,0,0
通常不是有效颜色值,它是完全透明的,而黑色的
Alpha
值是
255
。
///
<summary>
///
Empty color, used to mark unused color values.
///
</summary>
public
static
readonly
Color Empty
=
new
Color(
0
,
0
,
0
,
0
);