Brick Out in C#




Fig 1 - Screen Shot of Brick Out Game    



Fig 2 - UML Design of BrickOut Game Reverse engineered using WithClass 2000

Way back, I'd say about 1981 (ok maybe not so far back!), there was a game for the Apple II called Brick Out. The game was actually a bit more complex than the one I'm presenting here. The object of the game was to knock out all the brick by hitting a ball with a paddle against the bricks. This source code was provided at the time( in Apple Basic) and  boasted 'Hi-Res' Graphics. People are probably laughing at what was considered high resolution back then. Still it was a fun computer to learn game programming.

This game uses a timer to control the speed of the ball. The timer event handler draws the ball in its new position each time a timer Interval occurs, so changing this Interval changes the speed of the ball. Collisions of the Ball are also tested each time a timer Interval occurs. If the ball collides with something like a brick, or the side of the form, or the paddle, the ball will change to the appropriate direction. The paddle is divided up into different colllision sections, each section determines what vector velocity pair the ball will come off the paddle with. If the ball misses the paddle, the next ball is released from the left hand side of the form.

The Paddle is controlled by the right and left arrow keys on the keyboard. The game starts, when one of these keys is pressed.  Below is the code for interpreting the arrow keys on the form. This code requires that the Form's KeyPreview property is set to true.  This way when the arrow key is pressed, the form will trap the KeyDown event and you can interpret what key is pressed by looking at the KeyData:

Listing 1.1 - KeyDown Event for Left and Right Arrows

private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
string result = e.KeyData.ToString();
Invalidate(ThePaddle.GetBounds());
switch (result)
{
case "Left": // Move the Paddle Left and Invalidate
ThePaddle.MoveLeft();
Invalidate(ThePaddle.GetBounds());
if (timer1.Enabled == false)
timer1.Start();
break;
case "Right": // Move the Paddle Right and Invalidate
ThePaddle.MoveRight(ClientRectangle.Right);
Invalidate(ThePaddle.GetBounds());
if (timer1.Enabled == false)
timer1.Start();
break;
default:
break;
}

All drawn objects on the screen are pulled from a gif file and are inherited from the base class GameObject.  The GameObject knows how to load the image and draw the image in a specific position on the screen. Below are the drawing routines of the GameObject:

public void UpdateBounds()
{
MovingBounds = ImageBounds;
// Calculate the Offseted Rectangle containing the image
MovingBounds.Offset(Position);
}
public virtual void Draw(Graphics g)
{
// Calculate the Offseted Rectangle containing the image
UpdateBounds();
// Draw the Image in the correct position on the Form
g.DrawImage(TheImage, MovingBounds, 0, 0, ImageBounds.Width, ImageBounds.Height, GraphicsUnit.Pixel);
}

This behavior is inherited by all the ImageObjects: Ball, Brick, Row, and Paddle. The Row's Draw method  is overriden because it needs to do a little more than draw a single image. The overriden Draw method is shown below. It draws all of the remaining bricks in the row:

public override void Draw(Graphics g)
{
// Draw all the bricks in the row that have not been knocked out
for (int i = 0; i < kNumberOfBricks; i++)
{
if (Bricks[i] != null) // see if brick is removed
Bricks[i].Draw(g);
}
}

Improvements

For one thing, sound needs to be added. This is fairly easy to do and can be by downloading the Hangman Project on this site. I'll probably do this when I get a little more time. Also, in the classic BrickOut game, the Brick Rows have a space between the top of the Form and the first row of Bricks. That way the ball can bounce along the top and knock out a lot of bricks. Anyway, enjoy playing.


Similar Articles