Welcome to Dream.In.Code
Become an Expert!

Join 136,929 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 1,831 people online right now. Registration is fast and FREE... Join Now!




Make your own breakout style game in VB.NET

 
Reply to this topicStart new topic

> Make your own breakout style game in VB.NET, Step by step guide to coding your own breakout game

Rating  5
RodgerB
Group Icon



post 5 Jan, 2008 - 03:41 AM
Post #1


Make your own breakout style game in VB.NET

Hello 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.

IPB Image

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 Variables

The 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 Event

The 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 Timer

The 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 wink2.gif ).

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 bricks

The 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. tongue.gif

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 KeyPress

The 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


Conclusion

I 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.

Attached File  Breakout.zip ( 58.19k ) Number of downloads: 656


Thank you for reading this tutorial, I hope you learnt something new! smile.gif

This post has been edited by RodgerB: 5 Jan, 2008 - 08:46 PM
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!

gbertoli3
Group Icon



post 15 Aug, 2008 - 04:09 PM
Post #2
Great Post! I'm going to check out your Pong game right now!
Go to the top of the page
+Quote Post

vogash
*



post 17 Oct, 2008 - 04:07 AM
Post #3
Hi,

I see in this post that you use GDI++. How can i apply this project to work in Visual Studio 2003 not in VS 2008.
Is there any option to convert the project to work with VS 2003 or someone else knows the good reference for this game in VS 2003.
Thanks

This post has been edited by vogash: 17 Oct, 2008 - 04:50 AM
Go to the top of the page
+Quote Post


Fast ReplyReply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 12/3/08 10:30PM

Live Help!

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month