Creating a Tile-Matching Game in VB.NET 2012
Introduction
I love games; but I am in no sense of the word a gamer. My wife is the one and only gamer in my family. Also, the word gamer is quite relative. Why? Well, people think of gamers as young people with the best and biggest pcs playing games over the network with each other. This is not my wife, and most definitely not me. Our idea of fun is playing games such as mystery games, and tower defense games. We love having little in-house competitions (which I, strangely enough, win ). Games such as Angry Birds, Mystery P. I., Plants vs. Zombies, and Rise of Atlantis keep us busy through the night!
My wife always asks me if I could make a game or two (now over five) for her, and I always tend to agree to it. This next game I have tackled was a simple yet powerful Tile-matching game. This means that we have to match images that adjoin each other. This is what we'll do today.
Design
Not much of a design. Start up Visual Studio 2012 and start a new Visual Basic Windows Forms project. Name it anything you want. Design your layout to resemble Figure 1:

Figure 1 - Our Design
Code
First, our variables. Create the following objects inside your General Declarations section:
Private arrImages(4) As Image 'Our pics
Private RandGen As Random 'Random Number Generator
Private RandIndex As Integer
Dim PBTemp() As PictureBox 'Dynamic PictureBox
Private intScore As Integer 'Score
Private intPairsFound As Integer 'Total Items Found
Private timeEnd As DateTime 'Calculates Ending Time
Private timeDiff As TimeSpan 'Difference Between Start and End Times
Next, let us create our board, which will host our pictures:
Public Sub DrawPBGrid() 'Draws Grid of 225 blocks - 15 x 15
Dim NewLoc As New Point 'Location of Each New Block
arrImages(0) = My.Resources.ant
arrImages(1) = My.Resources.butterfly
arrImages(2) = My.Resources.dragonfly
arrImages(3) = My.Resources.ladybug
arrImages(4) = My.Resources.mosquito
RandGen = New Random(Now.Millisecond)
For CurrRow As Integer = 0 To 14 'Row By Row
For CurrCol As Integer = 0 To 14 'Column In Row By Column In Row
NewLoc.X = 2 + CurrRow * 30 'Height Of Block
NewLoc.Y = 2 + CurrCol * 30 'Width Of Block
Dim PB As New PictureBox 'New picturebox
ReDim Preserve PBTemp(CurrCol)
With PB 'Set Properties
.Name = CurrRow.ToString() & "_" & CurrCol.ToString 'Name Ex: 1_2 ( Row 1 _ Col 2 )
.BorderStyle = BorderStyle.FixedSingle 'Block Effect
.Location = NewLoc 'Set Position
.Width = 30 'Width
.Height = 30 'Height
.BackColor = System.Drawing.Color.White 'BackColour
RandIndex = RandGen.Next(0, 5)
.Image = arrImages(RandIndex)
AddHandler PB.MouseClick, AddressOf PB_MouseClick 'Event Handler Click
End With
PBTemp(CurrCol) = New PictureBox
PBTemp(CurrCol).Image = PB.Image
Me.Controls.Add(PB) 'Add PBs
Next
Next
End Sub
With the above sub, we produce 225 ( 15 x 15 ) blocks. These will host our pictures. We set each particular block's properties and add a random picture into it via our random generators. Most importantly, we added an event handler so that we will be able to click on each of these dynamic pictureboxes during runtime. When this sub is called, and the program is run, it will produce the following screen.

Figure 2 - Board
These pictures were added as resources, feel free to use them as well.
Add the next sub:
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
DrawPBGrid()
timeEnd = DateTime.Now 'Get Current Time
Dim minute As Double = System.Convert.ToDouble(5) '5 Minutes
Dim second As Double = System.Convert.ToDouble(0) '0 Seconds
timeEnd = timeEnd.AddMinutes(minute) 'Add Mintues
timeEnd = timeEnd.AddSeconds(second) 'Add Seconds
tmrLoop.Start()
End Sub
This is the code for our start button. It sets everything in motion. It draws the gaming board, and starts the count down timer, which gives 5 minutes.
Now things start to become interesting. What we need to do now is to use the common PictureBox click event handler, to determine our matches. Add the next code:
Private Sub PB_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs) 'Common Event Handler For PBs
Static intCounter As Integer 'How Many Times Clicked?
Static pb() As PictureBox 'Selected PictureBox(es)
Static colname() As String 'Which Column Is PictureBox(es) In?
Static rowname() As String 'Which Row Is PictureBox(es) In?
ReDim Preserve pb(intCounter) 'Resize Arrays According To Size of intCounter
ReDim Preserve colname(intCounter)
ReDim Preserve rowname(intCounter)
pb(intCounter) = New PictureBox 'New pictureBox
pb(intCounter) = DirectCast(sender, PictureBox) 'Store Selected PictureBox
'Obtain Column Name
colname(intCounter) = pb(intCounter).Name.ToString.Substring(0, pb(intCounter).Name.ToString.LastIndexOf("_"))
'Obtain Row Name
rowname(intCounter) = pb(intCounter).Name.ToString.Substring(pb(intCounter).Name.ToString.LastIndexOf("_") + 1)
If intCounter >= 1 Then 'If Clicked Twice
If pb(intCounter - 1).Image Is pb(intCounter).Image Then 'If Clicked Pictures Are The Same
'If Pictures In Same Row / Column
If colname(intCounter - 1) = colname(intCounter) OrElse rowname(intCounter - 1) = rowname(intCounter) Then
pb(intCounter - 1).BackColor = Color.Black 'Indicate Match
pb(intCounter).BackColor = Color.Black
pb(intCounter - 1).Image = Nothing 'Clear Pictures
pb(intCounter).Image = Nothing
intScore += 20 'Update Score
lblScore.Text = intScore
intPairsFound += 1
Scramble() 'Scramble Pictures
End If
End If
End If
intCounter += 1 'Increase intCounter With Each Click
End Sub
Not too difficult hey? Inside the above sub we have called the Scramble sub, let us add it now:
Private Sub Scramble() 'Replace Pictures Randomly
Dim RandGen As New Random(Now.Millisecond) 'Generate Random Number
For Each P As PictureBox In Me.Controls.OfType(Of PictureBox)() 'Loop Through PictureBox Grid
Dim RandIndex As Integer = RandGen.Next(0, 5) 'Generate New Random Picture
If P.BackColor <> Color.Black Then 'Skip Found Pairs
P.Image = arrImages(RandIndex) 'Replace Picture
Else
P.Image = Nothing
End If
Next
End Sub
Quite straightforward. We loop through all of the pictureboxes on the form. We then replace all of the pictures randomly, except for the pairs that have already been found. Add the final events and subs:
Private Sub ShowSummary() 'Shows Summary After Game Completion
Dim strSummary As String 'Summary String
'Compose String For Output
strSummary = "Summary" & Environment.NewLine & Environment.NewLine & _
"Pairs Found: " & intPairsFound.ToString & Environment.NewLine & Environment.NewLine & _
"SCORE: " & intScore.ToString
lblScore.Text = strSummary 'Write Text
End Sub
Private Sub tmrLoop_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrLoop.Tick
Dim strFinalOutput As String 'Output String
timeDiff = timeEnd - DateTime.Now
'Caclulate Difference Between Start and End
Dim output As TimeSpan = New TimeSpan(timeDiff.Hours, timeDiff.Minutes, timeDiff.Seconds)
strFinalOutput = "Time Left: " & output.ToString().Substring(3) 'Concatenates Time
lblTime.Text = strFinalOutput
If (timeDiff.Ticks < 0) Then 'If Time is Up
tmrLoop.Stop()
MessageBox.Show("Time's UP!!")
ShowSummary()
btnStart.Enabled = True
End If
End Sub
Private Sub btnEnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnd.Click
tmrLoop.Stop() 'Stop Timer
ShowSummary() 'Show Summary
End Sub
The ShowSummary sub is responsible for displaying our score, once the game is over or has been stopped. The tmrLoop_Tick event counts down the time (5 minutes we set up inside btnStart_Click). btnEnd stops the game and produces a score summary.
If you were to run this game now, you'd be able to select matching pairs. After a pair has been identified, that pair will turn black and the images will shuffle. This makes things a bit more interesting for the player, and a bit more difficult to match all the pairs. Your game play screen will look something like Figure 3.

Figure 3 - Playing the game
Conclusion
I am including the source code in zipped format below, just in case you have lost your way somehow. I hope you have enjoyed creating this simple yet powerful game and that you have benefited from it. Until next time, cheers!

Comments
great game
Posted by tim on 03/01/2013 04:45pmthis is a great game, thanx for sharing it. do you mind if i try to port it to an android? it may take a while to get it up, i'm in the middle of another project right now, but i can send it to you when you get done if you want. stop by my website and leave me a comment if it's ok to proceed. kitswv.com
Reply