More Helper Classes


Didn’t talk enough about helper classes in the last chapter? Yes we did. The two new classes you are going to use for the Tetris game are not discussed here in great detail and they are just stripped-down versions of the real classes you use later in this book. But they are still useful and help you to make the programming process of your game easier.

TextureFont Class

You already learned about the missing font support in XNA and you know that using bitmap fonts is the only option to display text in XNA (apart from using some custom 3D font rendering maybe). In the first games of this book you just used some sprites to display fixed text in the game or menu. This approach was very easy, but for your scoreboard you certainly need a dynamic font allowing you to write down any text and numbers the way you need it in the game.

Let’s go a little bit ahead and take a look at the TestScoreboard unit test in the TetrisGame class, which renders the background box for the scoreboard and then writes down all the text lines to display the current level, score, highscore, and number of lines you destroyed in the current game:

  int level = 3, score = 350, highscore = 1542, lines = 13; TestGame.Start("TestScoreboard",   delegate   {     // Draw background box     TestGame.game.backgroundSmallBox.Render(new Rectangle(       (512 + 240) - 15, 40 - 10, 290 - 30, 190));     // Show current level, score, etc.     TextureFont.WriteText(512 + 240, 50, "Level: ");     TextureFont.WriteText(512 + 420, 50, (level + 1).ToString());     TextureFont.WriteText(512 + 240, 90, "Score: ");     TextureFont.WriteText(512 + 420, 90, score.ToString());     TextureFont.WriteText(512 + 240, 130, "Lines: ");     TextureFont.WriteText(512 + 420, 130, lines.ToString());     TextureFont.WriteText(512 + 240, 170, "Highscore: ");     TextureFont.WriteText(512 + 420, 170, highscore.ToString()); }); 

You might notice that you are now using the TestGame class to start your unit test. For this test you use a couple of variables (level, score, and so on), which are replaced by the real values in the game code. In the render loop you first draw the background box and display it immediately to avoid display errors with sprites you draw later. Then you write down four lines of text with help of the WriteText method in the new TextureFont class at the specified screen positions. You actually call WriteText eight times to properly align all the numbers at the right side of your background box, which looks much nicer than just writing down everything in four lines.

After writing this unit test you will get a compiler error telling you that the TextureFont class does not exist yet. After creating a dummy class with a dummy WriteText method you will be able to compile and start the test. It will just show the background box, which is drawn in the upper-right part of the screen with help of the SpriteHelper class you learned about in the last chapter.

Before you even think about implementing the TextureFont class you will need the actual bitmap texture with the font in it to render text on the screen. Without a texture you are just doing theoretical work, and unit testing is about practical testing of game functionality. You will need a texture like the one in Figure 4-3 to display all the letters, numbers, and signs. You can even use more Unicode letters in bigger textures or use multiple textures to achieve that, but that would go too far for this chapter. Please check out the websites I provided at the top of the TextureFont class comment in the source code to learn more about this advanced topic.

image from book
Figure 4-3

Take a look at the implementation of the TextureFont class (see Figure 4-4). Calling the TextureFont class is very easy; you just have to call the WriteText method like in the unit test shown earlier. But the internal code is not very easy. The class stores rectangles for each letter of the GameFont.png texture, which is then used in WriteAll to render text by drawing each letter one by one to the screen. The class also contains the font texture, which is GameFont.png, a sprite batch to help render the font sprites on the screen, and several helper variables to determine the height of the font. For checking how much width a text will consume on the screen you can use the GetTextWidth method.

image from book
Figure 4-4

The internal FontToRender class holds all the text you want to render each frame, which is very similar to the process the SpriteHelper class uses to render all sprites on the screen at the end of each frame. In the same way SpriteHelper.DrawAll is called by BaseGame, TextureFont.WriteAll is also called and flushes everything on the screen and clears all lists. To learn more about the TextureFont class, check out the source code and run the unit tests or try stepping through the WriteAll method.

Input Class

Another new class that is used in the Tetris game is the Input class, which encapsulates all the input handling, checking, and updating you did in the previous chapters yourself. Chapter 10 talks about the Input class in greater detail and some nice classes that really need all the features from the Input class (see Figure 4-5).

image from book
Figure 4-5

As you can see, the Input class has quite a lot of properties and a few helper methods to access the keyboard, the gamepad, and the mouse data. It will be updated every frame with the help of the static Update method, which is called directly from the BaseGame class. For this game you are mainly going to use the key press and gamepad press methods like GamePadAJustPressed or KeyboardSpaceJustPressed. Similar to the RandomHelper class it is not hard to figure out how this class works, and you already implemented much of the functionally in the previous chapter. For more details and uses you can check out Chapter 10.

Sound Class

Well, you already had sound in the first game in Chapter 2 and you also used it in Chapter 3 for the Breakout game. To keep things simple and to allow you to add more sound functionally later without having to change any of the game classes, the sound management is now moved to the Sound class. Take a quick look at the class (see Figure 4-6). It looks very simple in this version, but in Chapter 9, which also talks about XACT in greater detail, you will extend the Sound class quite a bit and make it ready for your great racing game at the end of this book.

image from book
Figure 4-6

As you can see, all the sound variables are now in this class and the Game class no longer contains any sound variables. The Sound constructor is static and will be called automatically when you play a sound for the first time with the Play method. The Update method is called automatically from the BaseGame class.

The Sounds enum values and the TestPlayClickSound unit test depend on the actual content in your current game. These values will change for every game you are going to write from here on, but it is very easy to change the Sounds enum values. You might ask why you don’t just play the sounds with help of the cue names stored in XACT. Well, many errors could occur by just mistyping a sound cue and it is hard to track all changes in case you remove, rename, or change a sound cue. The Sounds enum also makes it very easy to quickly add a sound effect and see which ones are available through IntelliSense.

The Tetris game uses the following sounds:

  • BlockMove for moving the block left, right, or down. It is a very silent sound effect.

  • BlockRotate is used when you rotate the current block and it sounds very “whooshy.”

  • BlockFalldown is used when the current block reaches the ground and finally lands.

  • LineKill is played every time you manage to kill a line in the game.

  • Fight is played at the start of each game to motivate the player.

  • Victory is used when the player reaches the next level and contains an applause sound.

  • Lose is an old school dying sound and is played when the player loses the game.




Professional XNA Game Programming
Professional XNA Programming: Building Games for Xbox 360 and Windows with XNA Game Studio 2.0
ISBN: 0470261285
EAN: 2147483647
Year: 2007
Pages: 138

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net