Home | Gaming | Programming | Play Online | Contact | Keyword Query
Games++ Games & Game Programming

GAMES++
Games++ Home
Games++ Gaming
Games++ Programming
Beta Testing Games
Free Online Games
Hints & Cheats

BROWSER UTILITIES
E-mail This Page
Add to Favorites

SITE SEARCH

Web Games++

AFFILIATES
Cheat Codes
Trickster Wiki
Game Ratings
Gameboy Cheats
PlayStation Cheats
BlackBerry Games
Photoshop Tutorials
Illustrator Tutorials
ImageReady Tutorials

ADVERTISEMENT

Eater Game

By Mike Gold


Figure 1 - Playing the Eater Game

Source Code: EaterGame.zip

Description

This is a simple game written in C# in which the user moves a packman like player around the form and gobbles up red dots. The object is to get all the dots in as quick a time as you can. The design for the game is shown below:


Figure-2 - The UML for this game was reverse engineered using WithClass 2000

By examining the design, you can see that the eater game is not so difficult to understand because its simply a group of classes that are aggregates of the Form. Each instance of class draws itself on the Form and the methods of the class are called from the form to exercise the class's behavior.

The Sequence of Events is shown in the WithClass UML Diagram below after an arrow key to the right is pressed:


Figure-3 - Sequence of Events after a Right Key is pressed and the Eater hits a stone

The diagram above shows the flow of methods through the objects when a right arrow key is pressed and for those of you new to UML its known as a sequence diagram. The messages on the arrows map back to methods in the classes and each box with a vertical line represents an instance of the class in our Eater Game.

The code for the sequence above is shown below:

Listing 1 - KeyDown Event Handler

// KeyDown Event handled by the Form
private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{ 
//  Invalidate the Eater before moving it 
string result = e.KeyData.ToString();
Invalidate(TheEater.GetFrame());
switch (result)
{
 case "Left":
//  Move the Eater to the Left
   TheEater.MoveLeft(ClientRectangle);
   Invalidate(TheEater.GetFrame());
  break;
  case "Right":
//  Move the Eater to the Right
    TheEater.MoveRight(ClientRectangle);
    Invalidate(TheEater.GetFrame());
  break;
  case "Up":
//  Move the Eater to the Up
    TheEater.MoveUp(ClientRectangle);
    Invalidate(TheEater.GetFrame());
  break;
  case "Down":
//  Move the Eater to the Down
    TheEater.MoveDown(ClientRectangle);
    Invalidate(TheEater.GetFrame());
     break;
  default:
     break;
  } 

//  Check to see if the Eater ate a stone
   int hit = CheckIntersection();
  if (hit != -1)
  {
//  The Eater Ate a Stone, Increment the score, play a sound and remove the stone
     TheScore.Increment();
     PlaySoundInThread("hit.wav");
     Invalidate(TheScore.GetFrame());
     Invalidate(((Stone)Stones[hit]).GetFrame());
     Stones.RemoveAt(hit);

//  Check to see if the game is over
   if (Stones.Count == 0)
  {
    //  Game is over , all the stones are eaten,  show the time it took to eat  them
     MessageBox.Show("You Win!\nYour time is " + TheTime.TheString + " seconds.");
    Application.Exit();
   }

  }

In the Key Handler code above, each case of movement is handled for the Eater player. If the Eater finds a stone, the score is incremented and a stone is removed.

Drawing of the stones, the eater, the score, and the timer is all handled by the each of the respective classes. Below is the OnPaint method for the form to draw the board:

Listing 2 - Paining the Game Board

private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
   Graphics g = e.Graphics;
    g.FillRectangle(Brushes.White, 0, 0, this.ClientRectangle.Width,
                      ClientRectangle.Height); 
// draw the score
TheScore.Draw(g);

// draw the time
TheTime.Draw(g, TheSeconds);

// draw the stones 

for (int i = 0; i < Stones.Count; i++)
{
   ((Stone)Stones[i]).Draw(g);
} 

// also draw the eater 

TheEater.Draw(g);

}

Animation of the Eater is handled by using two bitmaps. One bitmap has the eater with its mouth open, the other with its mouth closed. The Eater is drawn on the odd pixels with the mouth open and the even pixels with the mouth closed. It also checks to see if it moved horizontally the last time or vertically. This could probably be expanded to 8 images, two for each direction the eater moves in.

Listing 3 - Drawing the Eater

public void Draw(Graphics g)
{
  Rectangle destR = new Rectangle(Position.X, Position.Y, EaterImage.Width, 
                              EaterImage.Height); 
Rectangle srcR = new Rectangle(0,0, EaterImage.Width, EaterImage.Height);

// make it look like the mouth is moving
if ( ((Position.X % 2 == 1) && ((Position.X - LastPositionX) != 0)) ||
       ((Position.Y % 2 == 1) && ((Position.Y - LastPositionY) != 0))
   )
   g.DrawImage(EaterImage, destR, srcR, GraphicsUnit.Pixel);
else
   g.DrawImage(EaterImage2, destR, srcR, GraphicsUnit.Pixel);

LastPositionX = Position.X;
LastPositionY = Position.Y;
}

Invalidation

Back in the days when people were programming Macintoshes (remember the toolbox!), even before Windows 3.1 came into existence there was the concept of Invalidating regions of the window. I must admit its not an intuitive concept, but seems to work well. The concept goes that when erasing and redrawing an area of the window, you don't simply erase and redraw the area. You "Invalidate" the part of the window you want redrawn. This minimizes flicker in that area. The actual drawing is done in the OnPaint Routine (Or Form1_Paint in this example). Anotherwords you invalidate a rectangular region you want to redraw, this forces the Form1_Paint to be called and go through the entire Form1_Paint routine. Everything in Form1_Paint is executed, but only the area of the screen that you Invalidated is actually drawn. In the Listing 1 Key Handler, the Eater area is first invalidated to erase the original position of the Eater and then the new area of where the eater is being drawn to after the move is invalidated. The effect to the eye is that the eater is actually moving. The eater can be made to "speed up" by increasing the increment at which the Position is changed when the key is being pressed.

Improvements

I was actually thinking of a few things that could be introduced to the game to give it more of a twist. The game can be changed to have the timer time down and the score could be based on the number of stones eaten in that time. A maze object could be introduced on the board to make it a little more challenging to get the stones. Maybe a bullet object could be created to allow the eater to shoot at the stones. Perhaps you'll see Eater II or Super Eater in the near future ;-)

About the Author: Mike Gold is President of Microgold Software Inc. and Creator of WithClass 2000 a UML Design Tool for C#. In the last few years Mike has consulted for companies such as Merrill Lynch and Chase Manhattan Bank in New York. He is been active in developing Visual C++ Applications for 10 years and looks forward to the possibilities in C#. You can reach him at techsupport@microgold.com.

Copyright © 1998-2007, Games++ All rights reserved. | Privacy Policy