Make your own breakout style game in VB.NETHello and welcome to this tutorial on creating your own breakout game. Before we start making the game, it would best have a little bit of insight into the history of breakout. Breakout was developed by Atari in 1976, and is a game played with 3 factors, the paddle, the ball and the bricks. Breakout was inspired by the 1972 hit Pong (
see here for my pong tutorial).
Basically, the idea of breakout is to hit all the bricks, and by hitting these bricks you recieve points (although we won't be programming the points in this tutorial, it is relatively easy to implement yourself). When all the bricks have been eliminated, you will move onto the next level (or exit the game, in our case).
Other implementations of the game include items that drop down when you hit the bricks, we won't be implementing these though, because we are only making a basic game.
Here is an image of the finished breakout game we will be have at the end.

Here are the topics we will be covering in this tutorial.
- Programming with GDI++ functions.
- Making a ball bounce.
- Making the paddle move according to the mouse position.
- Moving the ball.
- Game Flow.
- Hiding/Showing the Cursor.
- Exiting the game on Escape KeyPress.
- Creating an array of rectangles.
- Drawing an array of rectangles.
- Determining if a block is alive or not.
Ok, so now you are probably thinking, that seems like a lot of tasks to do? Well infact, its not a huge list, but not small either. This tutorial is aimed at
Intermediate programmers because of this reason (just because you can program it, doesn't mean you are going to get any sort of interlectual benefit from it).
First we will create our playing space. Our playing space will consist of:
- A name property of the form. Call it gameMain
- A Size of 640x480, so the Size property = 640, 480.
- DoubleBuffered rendering so the form won't flicker, so the DoubleBuffered property = True.
- We don't want the form to be resizable so, FormBorderStyle = FixedDialog
- We want the form to look neat, so set the BackColor property to a nice color.
- Add a timer control, call it tmrGame, set it's Interval property to 20 and set its Enabled property to True.
After doing this, we have finished with the form designer. We won't be doing anymore with it, because we are going to create a game dependent on the GDI++ graphics namespace.
1) The VariablesThe variables we will be using are:
Constants:- brickWidth - The default width the bricks will have.
- brickHeight - The default height the bricks will have.
- brickRows - The amount of rows of bricks we will be using.
- brickColumns - The amount of columns of bricks we will be using.
Brick Variables- brickArray() - The array of Rectangle we will be using to store the bricks in. We use an array, so the developer can have more control over the size of each individual element, etc, later on.
- isBrickEnabled() The boolean array that determines whether a brick is enabled or not.
Paddle Variables- gamePaddle - The Rectangle that will determine the position and size of the paddle.
Ball Variables- gameBall - The Rectangle that will determine the position and size of the ball.
- isBallGlued - The Boolean value that will determine whether the ball is stuck to the center of the paddle. The Y position must be set, or the ball will stay aligned with the center of the paddle, but not on the paddle.
Physics Variables- speed - The speed the ball will be moving at.
- xVel - The velocity of the X Axis for the ball.
- yVel - The velocity of the Y Axis for the ball.
Now that we understand the variables, and what they actually do, copy and paste the following code into the class:
CODE
#Region "Variables"
Private Const brickWidth As Integer = 75
Private Const brickHeight As Integer = 23
Private Const brickRows As Integer = 6 - 1
Private Const brickColumns As Integer = 6 - 1
Private brickArray(brickRows, brickColumns) As Rectangle
Private isBrickEnabled(brickRows, brickColumns) As Boolean
Private gamePaddle As Rectangle = New Rectangle(300, 434, 72, 10)
Private gameBall As Rectangle = New Rectangle(gamePaddle.X + 72 / 2 _
- (16 / 2), 432 - 16, 16, 16)
Private isBallGlued As Boolean = True
Dim speed As Single = 5
Dim xVel As Single = Math.Cos(speed) * speed
Dim yVel As Single = Math.Sin(speed) * speed
#End Region
We now have the variables added, lets get to the next section.
2) Loading up the game.Loading the game involves setting a rectangle for all instances in the brickArray. We will then hide the cursor, so it doesn't interupt our play.
CODE
#Region "Load Game"
Private Sub gameMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
loadBricks()
Windows.Forms.Cursor.Hide()
End Sub
#End Region
The
loadBricks() subroutine looks like so:
CODE
#Region "Paint Event"
Private Sub gameMain_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
' Loop through all enabled bricks and display them.
For row As Integer = 0 To brickRows
For column As Integer = 0 To brickColumns
If isBrickEnabled(row, column) Then _
e.Graphics.FillRectangle(Brushes.Red, brickArray(row, column))
Next
Next
' Show the ball and the paddle.
e.Graphics.FillRectangle(Brushes.Green, gameBall)
e.Graphics.FillRectangle(Brushes.DarkGreen, gamePaddle)
End Sub
#End Region
Once all the settings are loaded, we can start learning about the paint event, the main handler of our GDI++ based game.
3) The Paint EventThe Paint event is called every time we need to re-draw the form. We need to redraw the form very often, to make the ball movement move smoothly. You will see that is it being called everytime the
tmrGame timer is called with the
Me.Refresh method.
CODE
#Region "Paint Event"
Private Sub gameMain_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
' Loop through all enabled bricks and display them.
For row As Integer = 0 To brickRows
For column As Integer = 0 To brickColumns
If isBrickEnabled(row, column) Then _
e.Graphics.FillRectangle(Brushes.Red, brickArray(row, column))
Next
Next
' Show the ball and the paddle.
e.Graphics.FillRectangle(Brushes.Green, gameBall)
e.Graphics.FillRectangle(Brushes.DarkGreen, gamePaddle)
End Sub
#End Region
4) The Game TimerThe game timer controls all of the collisions, movement and bouncing involved with the ball and movement of the paddles. Copy and paste the following into your class.
CODE
#Region "Game Timer"
Private Sub tmrGame_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrGame.Tick
If Not isBallGlued Then _
gameBall.Location = New Point(gameBall.X + xVel, gameBall.Y + yVel)
' Check for top wall.
If gameBall.Location.Y < 0 Then
gameBall.Location = New Point(gameBall.Location.X, 0)
yVel = -yVel
End If
' Check for bottom wall (restart)
If gameBall.Location.Y - gameBall.Height > Me.Height Then
isBallGlued = True
gameBall.Location = New Point(gamePaddle.X + 72 / 2 _
- (gameBall.Width / 2), 432 - 16)
End If
' Check for left wall.
If gameBall.Location.X < 0 Then
gameBall.Location = New Point(0, gameBall.Location.Y)
xVel = -xVel
End If
' Check for right wall.
If gameBall.Location.X + gameBall.Width > Me.Width Then
gameBall.Location = New Point(Me.Width - gameBall.Width, _
gameBall.Location.Y)
xVel = -xVel
End If
' Check for paddle.
If gameBall.IntersectsWith(gamePaddle) Then
gameBall.Location = New Point(gameBall.X, gamePaddle.Y - gameBall.Height)
yVel = -yVel
End If
' Check for blocks
For rows As Integer = 0 To brickRows
For columns As Integer = 0 To brickColumns
If Not isBrickEnabled(rows, columns) Then Continue For
If gameBall.IntersectsWith(brickArray(rows, columns)) Then
isBrickEnabled(rows, columns) = False
If gameBall.X + 10 < brickArray(rows, columns).X Or _
gameBall.X > brickArray(rows, columns).X + brickArray(rows, columns).Width _
Then
xVel = -xVel
Else
yVel = -yVel
End If
End If
Next
Next
' Check for end of game.
If getBrickCount() = 0 Then
tmrGame.Stop()
Windows.Forms.Cursor.Show()
If MessageBox.Show("Would you like to play again?", "Play Again?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
loadBricks()
isBallGlued = True
Windows.Forms.Cursor.Hide()
gameBall.Location = New Point(gamePaddle.X + 72 / 2 - (gameBall.Width / 2), _
432 - 16)
tmrGame.Start()
Else
Application.Exit()
End If
End If
Me.Refresh()
End Sub
#End Region
Lets break down the code individually, it is important to understand what each part does.
The following will make sure when the ball is not glued to the paddle awaiting launch, it is going in the right direction.
CODE
If Not isBallGlued Then _
gameBall.Location = New Point(gameBall.X + xVel, gameBall.Y + yVel)
It would be tedious and repeatitive to give reason for checking for collisions with all four walls, but the same concept remains. Any wall that is meant to make the ball bounce, the ball will be made to contact the wall and invert the velocity. If it is the bottom wall, it will set the ball glued, and on top of the paddle, ready to be sent off by a mouse click. The same concept is shown below, where the ball is made to contact the top of the paddle and inverts the
yAxis velocity.
CODE
' Check for paddle.
If gameBall.IntersectsWith(gamePaddle) Then
gameBall.Location = New Point(gameBall.X, gamePaddle.Y - gameBall.Height)
yVel = -yVel
End If
Now we need to check if an enabled block has been hit by the ball. We will loop through all the rows and columns, ignore the bricks that aren't enabled, make the ball bounce of the brick and destroy it. We will need to check if the ball needs to invert on the x or y axis, so we will just check if it is on the far left or the far right. If it isn't, its the top or bottom (due to logical deduction

).
CODE
' Check for blocks
For rows As Integer = 0 To brickRows
For columns As Integer = 0 To brickColumns
If Not isBrickEnabled(rows, columns) Then Continue For
If gameBall.IntersectsWith(brickArray(rows, columns)) Then
isBrickEnabled(rows, columns) = False
If gameBall.X + 10 < brickArray(rows, columns).X Or _
gameBall.X > brickArray(rows, columns).X + brickArray(rows, columns).Width _
Then
xVel = -xVel
Else
yVel = -yVel
End If
End If
Next
Next
Check if there is no bricks left, and if so, prompt the user if he/she would like to restart the game. If so, reload the blocks, glue the ball to the paddle, hide the cursor again because we are restarting the game and restart the timer. If he/she does not want to play, exit the game.
CODE
' Check for end of game.
If getBrickCount() = 0 Then
tmrGame.Stop()
Windows.Forms.Cursor.Show()
If MessageBox.Show("Would you like to play again?", "Play Again?", MessageBoxButtons.YesNo, _
MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
loadBricks()
isBallGlued = True
Windows.Forms.Cursor.Hide()
gameBall.Location = New Point(gamePaddle.X + 72 / 2 - (gameBall.Width / 2), _
432 - 16)
tmrGame.Start()
Else
Application.Exit()
End If
End If
5) Get the amount of bricksThe following function will get the amount of currently enabled bricks. Copy and paste the function into a class.
CODE
#Region "Get Amount of Bricks"
Function getBrickCount() As Integer
Dim Count As Integer = 0
For Each brick As Boolean In isBrickEnabled
If brick = True Then Count += 1
Next
Return Count
End Function
#End Region
Basically it works by looping through all boolean values in the array, and incrementing the count if any of them are true.
6) Move the paddle according to the mouse's position.The following code will move the paddle according to the mouse's position. It maintains
isBallGlued's purpose, and makes sure the paddle doesn't go off the screen when trying to have the paddle use the mouse's position.
CODE
#Region "Move Paddle According to Mouse Position"
Private Sub gameMain_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
If e.X > 0 And e.X < Me.Width - 72 Then _
gamePaddle.Location = New Point(e.X, gamePaddle.Y)
If isBallGlued Then
gameBall.Location = New Point(gamePaddle.X + 72 / 2 - (gameBall.Width / 2), _
432 - 16)
End If
End Sub
#End Region
7) Launch ball when user clicks, if the ball is glued.If the ball is glued, the user can launch the ball by clicking. Much like a pinball machine.

CODE
#Region "Launch Ball"
Private Sub gameMain_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick
If e.Button = Windows.Forms.MouseButtons.Left Then
' Launch the ball.
If isBallGlued Then isBallGlued = False
End If
End Sub
#End Region
8) Quit game on Escape Keypress, and Pause on P KeyPressThe following code will exit the game on an escape keypress, and toggle pausing on and off if 'P' has been pressed.
CODE
#Region "Quit on Escape Key Press and Pause on P Key Press"
Private Sub gameMain_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
' Exit
If e.KeyCode = Keys.Escape Then Application.Exit()
' Toggle Paused
If e.KeyCode = Keys.P Then _
If tmrGame.Enabled Then tmrGame.Stop() _
Else tmrGame.Start()
End Sub
#End Region
ConclusionI hope this tutorial shed some light on how you can create your own Breakout game. I have attached the source, so you can quickly read through the code yourself if you'd like.
Breakout.zip ( 58.19k )
Number of downloads: 650Thank you for reading this tutorial, I hope you learnt something new!
This post has been edited by RodgerB: 5 Jan, 2008 - 08:46 PM