《XNA高级编程:Xbox 360和Windows》4-4

4.4更多辅助类


     上一章我们讨论了很多辅助类的知识,本章并不会特别详细地讲解 Tetris 游戏中要用到的两个新辅助类,因为它们是本书后面要用到的真正的类的精简版本。但它们还是很有用的,可以让您的游戏开发过程更加容易。

TextureFont

     您已经了解到 XNA 本身不支持字体,唯一一个显示文本的方式就是使用位图字体(也可能使用自定义的 3D 字体渲染方式)。在本书的前几个游戏中,您只是使用了一些 sprites 在游戏或者菜单中显示固定的文本内容。这种方式很简单,但在实现记分板功能的时候,您很显然需要动态字体支持,这样才可以显示任何游戏中需要的文本和数字内容。

     现在让我们稍微超前一点,先看看 TetrisGame 类中的 TestScoreboard 单元测试,它的作用是渲染记分板的背景区域,并显示游戏的当前级别、得分、最高分以及消除的行数:

int  level  =   3 , score  =   350 , highscore  =   1542 , lines  =   13
TestGame.Start(
" TestScoreboard " ,
    
delegate
    
{
        
// Draw background box
        TestGame.game.backgroundSmallBox.Render(new Rectangle(
            (
512 + 240- 1540 - 10290 - 30190));
        
// Show tetris grid in center of screen
        TestGame.game.tetrisGrid.Draw(new GameTime());
        
// Show current level, score, etc.
        TextureFont.WriteText(512 + 24050"Level: ");
        TextureFont.WriteText(
512 + 42050, (level + 1).ToString());
        TextureFont.WriteText(
512 + 24090"Score: ");
        TextureFont.WriteText(
512 + 42090, score.ToString());
        TextureFont.WriteText(
512 + 240130"Lines: ");
        TextureFont.WriteText(
512 + 420130, lines.ToString());
        TextureFont.WriteText(
512 + 240170"Highscore: ");
        TextureFont.WriteText(
512 + 420170, highscore.ToString());
    }
);

     请注意此处使用的是 TestGame 类来启动单元测试。该测试中使用了几个变量( level score 等等),在具体的游戏代码中它们会被真实的数据取代。在渲染循环中,首先画出背景区域并立即显示出来,以避免稍后绘制 sprites 时出现错误。然后,使用 TextureFont 类中的 WriteText 方法在指定的屏幕位置上画出四行文字。实际上 WriteText 被调用了 8 次,是为了让数字在背景区域内靠右对齐,这样看起来更好看一点。

     写完该单元测试,会得到一个编译错误,告诉您 TextureFont 类还不存在。创建一个包含 WriteText 伪方法的伪类(即 TextureFont 类)之后,就可以编译并开始测试了,不过此时只在屏幕的右上角显示背景区域。

     在考虑实现 TextureFont 类之前,您要有包含字体的位图素材,这样才能在屏幕上渲染文本。没有素材的话您仅仅是在做理论工作,而单元测试却是关乎游戏功能的实践性测试。您需要一个如图 4-3 所示的素材,来显示所有的字母、数字和符号。您也可以使用更大的包含更多 Unicode 字符的素材,或者使用多个素材来达到同样的目的,不过这已经超出了本章要讨论的范围。有关这个高级主题,您可以查看一下源代码 TextureFont 类的注释中所列出的几个网址,来了解更多的相关知识。

(译者注:这几个网址是:

http://blogs.msdn.com/garykac/archive/2006/08/30/728521.aspx

http://blogs.msdn.com/garykac/articles/732007.aspx

http://www.angelcode.com/products/bmfont/

 

4-3

     接下来看一下 TextureFont 类的实现(见图 4-4 )。 TextureFont 类的调用很简单,就像前面的那个测试一样,只需调用 WriteText 方法。但其内部的代码实现并不那么简单。该类为素材 GameFont.png 中的每个字符都生成一个 Rectangle 对象实例,然后在 WriteAll 方法中把要渲染的文本逐个字符地画到屏幕上。它还包含了其它几个变量,比如字体素材即 GameFont.png ,用于渲染 sprites SpriteBatch 实例,以及用于确定字体高度的相关变量。如果要获取给定文本的宽度,可以使用 GetTextWidth 方法。
图4-4

4-4

     其中 FontToRender 类用来保存每一帧要渲染的文本内容,它很像 SpriteHelper 类在每一帧结尾时渲染 sprites 的过程。与 BaseGame 调用 SpriteHelper.DrawSprites 方法一样, TextureFont.WriteAll 也会被 BaseGame 调用,把所有内容绘制到屏幕上,然后清空所有列表。如果想进一步了解 TextureFont 类,请查看本章的源代码,运行单元测试,或者试着一步步调试 WriteAll 方法。

Input

     Tetris 游戏中要使用的另一个新辅助类是 Input 类,它封装了前几章中您做过的所有输入处理、检测以及更新操作。第十章将更详细地讨论 Input 类,而且有些类非常需要 Input 类提供的相关操作(如图 4-5 )。
图4-5

4-5

     可以看到, Input 类拥有非常多的属性以及一些用于访问键盘、 gamepad 和鼠标的方法。 BaseGame 类直接调用 Input 类的静态 Update 方法,这样每一帧它都会被更新。而本游戏中您将主要使用键盘和 gamepad 被按下时的相关处理方法,例如 GamePadAJustPressed KeyboardSpaceJustPressed 。和 RandomHelper 类一样,您也会很容易地理解该类如何工作,而且前一章您已经实现了大部分功能了。有关该类更多内容请参照第十章。

Sound

     关于声音的处理,在第二章的第一个游戏以及第三章的 Breakout 游戏中您已经接触过了。为了简单起见,以及今后在添加更多声音功能时不至于修改已有的代码,本章中把声音的管理都转移到了 Sound 类中。如图 4-6 显示了该类的信息。该版本看起来很简单,但是到了第九章,会进一步讨论 XACT 的内容,您将对 Sound 类进行大量的扩展,以便为本书最后要做的赛车游戏做好准备。
图4-6

4-6

     可以看出,所有的声音变量都被放到了该类中, Game 类中不再包含任何声音变量。 Sound 类的构造函数是静态的,它会在您第一次调用 Play 方法播放声音的时候自动被调用。其 Update 方法将被 BaseGame 类自动调用。

     其中 Sounds 枚举值以及 TestPlayClickSound 单元测试取决于您要做的当前游戏的实际内容。这些值将随着每一个游戏而改变,不过更改 Sounds 的枚举值也很简单。您可能会问为什么不直接使用保存在 XACT 中的 cue names 来播放声音?理由是,仅仅是误输入 sound cue 的话就会产生很多错误,而且万一您移除、重命名或者变更 sound cue 的话会很难跟踪所有的变化。使用 Sounds 枚举可以很容易地添加一个新的声效,而且通过编辑器的智能感知系统可以知道都有哪些声效可用。

Tetris 游戏使用了如下一些声音:
  • BlockMove:用于方块向左、向右或者向下移动时,该声效非常非常小
  • BlockRotate:用于旋转方块时,它听起来非常地“whooshy.
  • BlockFalldown:用于方块落地时
  • LineKill:用于消除一行时
  • Fight:用于游戏开始时激励玩家
  • Victory:用于玩家升级时,伴有鼓掌欢呼声
  • Lose:用于玩家输掉游戏时
图4-3

转载于:https://www.cnblogs.com/AlexCheng/archive/2010/05/11/2120323.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值