Game Development of .Nettrix: GDI+ and Collision Detection - The Game Engine
(Page 20 of 22 )
Now that all the base classes are coded, you’ll finish the main procedures.
In the first drafts for the game engine, you used the form procedures to call methods in your base classes, so you could see if they were working well. Now, the game engine must be coded to implement the features defined in the game proposal, stated earlier in this chapter. Remind yourself of the pseudo-code defined in the game project.
Form_Load
Creates an object (named currentBlock) of block class
FormKeyPress
If Left Arrow was pressed, call Left method of currentBlock
If Right Arrow was pressed, call Right method of currentBlock
If Up Arrow was pressed, call Rotate method of currentBlock
If Down Arrow was pressed, call Down method of currentBlock
TimerTick
If there is no block below currentBlock,
and the currentBlock didn't reach the bottom of the screen then
Call the Down method of currentBlock
Else
Stop the block
If it's at the top of the screen then
The game is over
If we filled any horizontal lines then
Increase the game score
Erase the line
Create a new block at the top of the screen
Before starting to translate this pseudo-code to C#, it’s important to stress two points:
- It’s not common to use timer objects to control games. The timer object doesn’t have the necessary precision or accuracy (you can’t trust it entirely when dealing with time frames less than 15 milliseconds). But for games like .Nettrix, the levels of accuracy and precision available with the timer are adequate (remember that you are trying to make the production of this game as simple as possible). In the next chapter, you’ll see a GDI+ application that runs at full speed, without using a timer.
- It’s not common in game programming to put the game engine code in a form. Usually you create a GameEngine class that deals with all the game physics and rules (as you’ll see in the next chapter).
Looking back at the pseudo-code, you see the following instruction:
If it's at the top of the screen then
This tests if the block is at the top of the screen. Reviewing your Block class, you see that you have no direct way to retrieve the block Top position, so you would have to test each of the Top positions of the block’s composing squares. To solve this, make a final adjustment to the Block class, including a new method, as depicted in the next code listing:
public int Top() {
return Math.Min(square1.location.Y, Math.Min
(square2.location.Y, Math.Min(square3.location.Y,
square4.location.Y)));
}
Now you’re ready to finish your program. Based on the preceding pseudocode and on some minor changes made in the game coding phase, the code for the form will be as follows:
private Block CurrentBlock;
private int score = 0;
private bool stillProcessing = false;
private void tmrGameClock_Tick(object sender, System.EventArgs e) {
int erasedLines;
// Prevents the code from running if the previous tick
// is still being processed.
if (stillProcessing) return;
stillProcessing = true;
// Manage the falling block.
if (!CurrentBlock.Down()) {
if (CurrentBlock.Top() == 0) {
// Test for Game over.
tmrGameClock.Enabled = false;
CmdStart.Enabled = true;
MessageBox.Show("GAME OVER", ".NETTrix",
MessageBoxButtons.OK, MessageBoxIcon.Stop);
stillProcessing = false;
return;
}
// Increase score based on # of deleted lines.
erasedLines = GameField.CheckLines();
if (erasedLines > 0) {
score += 100 * erasedLines;
lblScoreValue.Text = score.ToString();
PicBackground.Invalidate(); //Force the window to repaint.
Application.DoEvents();
GameField.Redraw();
}
// Replace the current block...
CurrentBlock = new Block(new Point (GameField.SquareSize*6,0), NextBlock.BlockType);
CurrentBlock.Show(PicBackground.Handle);
}
stillProcessing = false;
}
Compare the preceding code listing with the previous pseudo-code to make sure you understand each line of code.
The Load event for the form and the KeyDown event and the code for the Start button remain unchanged. The final version of .Nettrix has now been coded. When the game is run, it looks like the screen shown in Figure 1-32.

Figure 1-32. The final version of .Nettrix
You can now play your own homemade clone of Tetris, and are ready to improve it, with the changes discussed in the next section.
This chapter is from Beginning .NET Game Programming in C#, by David Weller, et al., (Apress, 2004, ISBN: 1590593197). Check it out at your favorite bookstore today.
Buy this book now. |
Next: Adding the Final Touches >>
More .NET Articles
More By Apress Publishing