.Netterpillars: Artificial Intelligence and Sprites, Part 2 - Coding for the Introduction Screen
(Page 8 of 11 )
Now is a good time to create an intro screen for your game. Our suggestion is shown in Figure 2-17, but feel free to use your artistic talent to improve it.

Figure 2-17. The .Netterpillars splash screen
The Main procedure must be changed to reflect the workflow diagram created in the project phase.
public static void Main(string [] args) {
frmSplash WinSplash;
frmGameField WinGameField;
frmGameOver WinGameOver = new frmGameOver();
int LastTick=0; int DesiredFrameRate = 10;
// Create the game engine object.
objGameEngine = new GameEngine();
WinSplash = new frmSplash();
while ( WinSplash.ShowDialog()==DialogResult.OK) {
WinGameField = new frmGameField();
WinGameField.Show();
Application.DoEvents();
// Create a copy of the background image to allow
erasing the sprites.
GameEngine.BackgroundImage =(Image)
WinGameField.PicGameField.Image.Clone();
objGameEngine.CreateGameField
(WinGameField.PicGameField.Handle);
while ( !objGameEngine.GameOver) {
if (!objGameEngine.Paused) {
// EXTRA: Force a Frame rate of 10 frames per
second on maximum.
if (System.Environment.TickCount-
LastTick>=1000/DesiredFrameRate) {
MoveComputerCharacters();
objGameEngine.Render();
LastTick = System.Environment.TickCount;
}
}
Application.DoEvents();
}
WinGameOver.ShowDialog();
WinGameField.Dispose();
}
objGameEngine = null;
WinSplash.Dispose();
WinGameOver.Dispose();
}
That’s it. You can now play with different field sizes, number of mushrooms, and netterpillars. But after playing a couple of times, you’ll soon discover that when you run your game a second time without making any configuration changes, your properties don’t get reset; so, among other things, you’ll start with the last quantity of mushrooms (that is, without the ones that were eaten). And worst of all: If the game field screen is being created for each game, your handle (passed to the objGameEngine constructor) becomes invalid.
Since you can’t simply move the objGameEngine creation to inside the loop (you’ll need it in the configuration screen, and if you re-create the object, the previous configuration will be lost), a solution is to create a new method to reset the game variables, which can be called just after the program Game Over loop. You can call this method CreateGameField, and move all the code from the constructor to it, including the parameter that receives the window handle.
We have shown these details to clarify a point: A game project, as any other project, will have problems en route. The better the project, the less unexpected the behavior in the coding phase. Nevertheless, there’s no way to guarantee immediate success. Don’t be ashamed to go back and correct everything if you think that it’ll make your game faster, more stable, or easier to update with new features.
Another detail that requires extra care is the code for setting the game field size: When you resize the game field, the game field window must be resized accordingly. You must do that in the Load event of the frmGameField window.
private void frmGameField_Load(System.Object sender,
System.EventArgs e) {
PicGameField.Location = new Point(0, 0);
PicGameField.Size = new Size
(MainGame.objGameEngine.Width*Sprite.IMAGE_SIZE,
MainGame.objGameEngine.Height*Sprite.IMAGE_SIZE);
this.ClientSize = PicGameField.Size;
}
With this last little adjustment, your code will work. But you don’t have code for the game over yet. We’ll show that next.
Coding for Game Over
Looking back at the game proposal, you can see that we stated “The game is over when all the players die (computer or human ones), or when the last mushroom is eaten.”
Since you have a property stating whether a player is dead or not and a property that stores the number of mushrooms (that is already reduced every time a mushroom is eaten), all you need to do is include the code in the Render procedure to test the preceding conditions and set the GameOver property to True if one of the requirements is met.
public void Render() {
// Move the Netterpillars.
MoveNetterpillars();
// If all Netterpillars die - GameOver.
GameOver = true;
for(int i=0; i<NetterpillarNumber; i++) {
if (!netterPillars[i].IsDead) {
GameOver = false;
}
}
// If all mushrooms got eaten - Game Over.
if (MushroomNumber==0) {
GameOver = true;
}
}
You mustn’t forget to remove the code for forcing the game to finish when the Esc key is pressed on the keyboard event handler for the frmGameField, unless you need this behavior in your finished game.
Although the code for the game over works fine, it can be improved if you include a screen with game statistics—such as the netterpillar’s size—so players can have clearer information about how well they played. Such a screen is added in the “Adding the Final Touches” section; for now, let’s alter your code to include a real computer-controlled competitor.
This chapter is from Beginning .NET Game Programming in C# by Ellen Hatton et al. (Apress, 2004, ISBN: 1590593197). Check it out at your favorite bookstore today. Buy this book now.
|
Next: Final Version: Coding the Netterpillars AI >>
More ASP.NET Articles
More By Apress Publishing