Another month, another game…
Today, I will show you how to create a Tile Slide game with Visual Basic.NET.
What Is a Tile Slider Game?
A tile slider, sliding puzzle, sliding block puzzle, or sliding tile puzzle is a combination puzzle in which a player has to slide pieces along certain routes on a board to establish a certain end-configuration. Sliding puzzles are mostly two-dimensional in nature and you are not allowed to lift a piece off the board.
Let’s create the game!
Design
Start a new Visual Basic Windows Forms project. You may name it anything you desire; I have named my project HTG_TileSlide. When the loaded form appears, design it as displayed in Figure 1:

Figure 1: Main form design
On the form, you need to include the a MainMenu with the following items and subitems:
- Load Picture
- Shuffle
- Size:
- 3 x 3
- 4 x 4
- 5 x 5
- OpenFileDialog
- Timer
- Panel
Feel free to name the objects differently than I have; just remember having done so when you code them. Add a User Control to your project (again, name it anything you want). Design it to resemble Figure 2.

Figure 2: User Control design
On the User Control, make sure you have the following objects:
- Button
- PictureBox
Code
Open the code window for your User Control and add the following fields:
Private pntImage As Point
Private intIndex As Integer
pntImage is used to keep track of each tile object’s position. intIndex is used to keep track of the tile’s index. Add the following Properties to your User Control:
Public ReadOnly Property Index() As Intege
Get
Return intIndex
End Get
End Property
Public ReadOnly Property ImageSize() As Size
Get
Return Me.picTile.Size
End Get
End Property
The Index property will be used in conjunction with intIndex. ImageSize gets and sets the image’s size depending on which Size menu option was selected. Add the Tile Sub procedure, which is responsible for setting each tile’s position:
Public Sub Tile(ByVal imImage As Image, ByVal ptStart As Point)
picTile.Image = imImage
pntImage = ptStart
End Sub
Add the Paint event for the Tile User Control. This event creates all the tiles:
Private Sub picTile_Paint(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.PaintEventArgs) _
Handles picTile.Paint
If Not (picTile.Image Is Nothing) Then
Dim g As Graphics = e.Graphics
g.DrawImage(picTile.Image, New _
Rectangle(New Point(0, 0), New Size(picTile.Width, _
picTile.Height)), New Rectangle(pntImage, _
New Size(picTile.Width, picTile.Height)), _
GraphicsUnit.Pixel)
End If
End Sub
Now, let’s proceed with the Form’s code.
Add the following fields to your Form:
Private Const intSquare As Integer = 64
Private Const intWidth As Integer = 62
Private intNumberOfRows As Integer = 3
Private intNumberOfCols As Integer = 3
Private rndRandom As Random
Private tilBlank As Block
Private blnLoaded As Boolean
Dim intCountDown As Integer
Private tilTiles(,) As ucTile
Friend WithEvents tilLast As ucTile
You set the size of each tile with intSquare and intWidth. You set the number of rows and columns next. You create a random object that you will use when shuffling the board. Next, you create a Block object—you will create the Block structure later. blnLoaded determines if an image has been loaded. tilTiles and tilLast are User Control objects that will be used in playing the game.
Load the game board and its associated objects:
Private Sub frmMain_Load(ByVal sender As System.Object,_
ByVal e As System.EventArgs) Handles MyBase.Load
Create(intNumberOfRows, intNumberOfCols)
End Sub
Public Sub Create(ByVal intRows As Integer, _
ByVal intCols As Integer)
Dim index As Integer = 0
ReDim tilTiles(intRows, intCols)
pnlTiles.Size = New Size(intSquare * intRows + 4, _
intSquare * intCols + 4)
pnlTiles.Location = New Point(4, 4)
Me.ClientSize = New Size(pnlTiles.Size.Width + 6, _
pnlTiles.Size.Height + 6)
Dim Row, Col As Integer
For Row = 0 To intRows - 1
For Col = 0 To intCols - 1
tilTiles(Row, Col) = New ucTile(intSquare, _
intSquare, index)
tilTiles(Row, Col).Parent = Me.pnlTiles
tilTiles(Row, Col).Location = New Point(Col *_
intSquare, Row * intSquare)
index += 1
Next
Next
End Sub
The Create sub procedure creates the 3 x 3 board. Later on, you will create each Menu Size event to enable the board to expand to 4 x 4 and 5 x 5.
Load the Picture:
Private Sub MenuLoadPicture_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles MenuLoadPicture.Click
OpenFileDialog1.Filter = "All Picture Formats _
(*.jpg,*.bmp, *.gif, *.png)|*.jpg;*.bmp;*.gif;*.png"
OpenFileDialog1.ShowDialog()
Dim intRow As Integer
Dim intCol As Integer
For intRow = 0 To intNumberOfRows - 1
For intCol = 0 To intNumberOfCols - 1
Try
tilTiles(intRow, intCol).Dispose()
Catch ex As Exception
End Try
Next
Next
Create(intNumberOfRows, intNumberOfCols)
Dim intXThumb As Integer = intWidth * intNumberOfRows
Dim intYThumb As Integer = intWidth * intNumberOfRows
Dim imgImage As Image = _
Image.FromFile(OpenFileDialog1.FileName)
imgImage = imgImage.GetThumbnailImage(intXThumb, _
intYThumb, Nothing, System.IntPtr.Zero)
For intRow = 0 To intNumberOfRows - 1
For intCol = 0 To intNumberOfCols - 1
tilTiles(intRow, intCol).Tile(imgImage, _
New Point(intCol * intWidth, intRow * intWidth))
Next
Next
tilBlank = New Block(intNumberOfRows - 1, _
intNumberOfCols - 1)
blnLoaded = True
End Sub
The MenuLoadPicture_Click event fires when a user has chosen the ‘Load Picture’ menu item. It allows you to browse for a picture. Once a valid picture has been chosen, the picture gets broken up into thumbnails according to which size option has been selected. In the default case, the chosen picture has been broken up into nine thumbnails to fit its 3 x 3 grid.
Figure 3 (broken up into 16 pieces) shows a picture of Namaqualand in South Africa. Look at the blue skies! This particular region is very barren and dry most of the year, except for in South Africa’s spring (from September onwards). I was fortunate enough to visit this region in 2016.

Figure 3: A picture is loaded
Shuffle the tiles:
Private Sub MenuShuffle_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MenuShuffle.Click
tilLast = tilTiles(intNumberOfRows - 1, intNumberOfCols - 1)
tilLast.Visible = False
tilTiles(intNumberOfRows - 1, _
intNumberOfCols - 1).Visible = False
Randomize()
End Sub
Protected Sub Randomize()
rndRandom = New Random()
intCountDown = 64 * intNumberOfRows * intNumberOfCols
tmrTime.Interval = 1
tmrTime.Enabled = True
End Sub
Private Sub tmrTime_Tick(ByVal sender As Object, _
ByVal e As EventArgs) Handles tmrTime.Tick
Dim intCol As Integer = tilBlank.intCol
Dim intRow As Integer = tilBlank.intRow
Select Case (rndRandom.Next(4))
Case 0
intCol += 1
Case 1
intCol -= 1
Case 2
intRow += 1
Case 3
intRow -= 1
End Select
If (intCol >= 0 And intCol < intNumberOfCols And _
intRow >= 0 And intRow < intNumberOfRows) Then
Shift(intCol, intRow)
End If
intCountDown = intCountDown - 1
If (intCountDown = 0) Then
tmrTime.Stop()
End If
End Sub
Private Sub Shift(ByVal intCol As Integer, _
ByVal intRow As Integer)
tilTiles(intRow, intCol).Location = New _
Point(tilBlank.intCol * intSquare, _
tilBlank.intRow * intSquare)
tilTiles(tilBlank.intRow, tilBlank.intCol) = _
tilTiles(intRow, intCol)
tilTiles(intRow, intCol) = Nothing
tilBlank = New Block(intRow, intCol)
End Sub
A Random number gets generated and the timer gets enabled. Depending on which number was generated, the tiles shift accordingly. Figure 4 shows the result.

Figure 4: Shuffle
Program the game play:
Private Sub frmMain_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) _
Handles MyBase.KeyDown
If blnLoaded = False Then Return
If (e.KeyCode = Keys.Left And tilBlank.intCol < _
intNumberOfCols - 1) Then
Shift(tilBlank.intCol + 1, tilBlank.intRow)
ElseIf (e.KeyCode = Keys.Right And tilBlank.intCol > _
0) Then
Shift(tilBlank.intCol - 1, tilBlank.intRow)
ElseIf (e.KeyCode = Keys.Up And tilBlank.intRow < _
intNumberOfRows - 1) Then
Shift(tilBlank.intCol, tilBlank.intRow + 1)
ElseIf (e.KeyCode = Keys.Down And tilBlank.intRow > _
0) Then
Shift(tilBlank.intCol, tilBlank.intRow - 1)
End If
e.Handled = True
GameOver()
End Sub
Private Sub pnlTiles_MouseDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles pnlTiles.MouseDown
If blnLoaded = False Then Return
Dim intRow As Integer = e.Y \ intSquare
Dim intCol As Integer = e.X \ intSquare
If (intCol = tilBlank.intCol) Then
If (intRow < tilBlank.intRow) Then
Dim intTempRow As Integer
For intTempRow = tilBlank.intRow - 1 To intRow Step -1
Shift(intCol, intTempRow)
Next
ElseIf (intRow > tilBlank.intRow) Then
Dim intTempRow As Integer
For intTempRow = tilBlank.intRow + 1 To intRow
Shift(intCol, intTempRow)
Next
End If
ElseIf (intRow = tilBlank.intRow) Then
If (intCol < tilBlank.intCol) Then
Dim intTempCol As Integer
For intTempCol = tilBlank.intCol - 1 To intCol Step -1
Shift(intTempCol, intRow)
Next
ElseIf (intCol > tilBlank.intCol) Then
Dim intTempCol As Integer
For intTempCol = tilBlank.intCol + 1 To intCol
Shift(intTempCol, intRow)
Next
End If
End If
GameOver()
End Sub
Private Sub GameOver()
Dim blnFinish As Boolean = True
Dim intIndex As Integer
Dim intRow As Integer
Dim intCol As Integer
For intRow = 0 To intNumberOfRows - 1
For intCol = 0 To intNumberOfCols - 1
If ((intIndex <> intNumberOfRows * intNumberOfCols) _
And Not (tilTiles(intRow, intCol) Is Nothing)) _
Then
blnFinish = blnFinish And (tilTiles(intRow, _
intCol).Index = intIndex)
End If
intIndex += 1
If Not blnFinish Then Return
Next
Next
If blnFinish Then
tilTiles(intNumberOfRows - 1, intNumberOfCols - 1) = _
tilLast
tilTiles(intNumberOfRows - 1, _
intNumberOfCols - 1).Visible = True
MessageBox.Show("You Win", "Game Over", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
tilBlank = New Block(intNumberOfRows - 1, _
intNumberOfCols - 1)
End If
End Sub
When the desired keys are pressed or the mouse event occurs, the tile objects should update their locations. Once the picture is correct, the GameOver sub gets called, notifying the user that he or she has won.

Figure 5: The game in action
Next, add the events to resize the game board according to which Size Menu option was selected:
Private Sub MenuSize3_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MenuSize3.Click
If (MenuSize3.Checked) Then Return
Clear()
MenuSize3.Checked = True
intNumberOfRows = 3
intNumberOfCols = 3
Create(intNumberOfRows, intNumberOfCols)
End Sub
Private Sub MenuSize4_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MenuSize4.Click
If (MenuSize4.Checked) Then Return
Clear()
MenuSize4.Checked = True
intNumberOfRows = 4
intNumberOfCols = 4
Create(intNumberOfRows, intNumberOfCols)
End Sub
Private Sub MenuSize5_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MenuSize5.Click
If (MenuSize5.Checked) Then Return
Clear()
MenuSize5.Checked = True
intNumberOfRows = 5
intNumberOfCols = 5
Create(intNumberOfRows, intNumberOfCols)
End Sub
Private Sub Clear()
MenuSize3.Checked = False
MenuSize4.Checked = False
MenuSize5.Checked = False
Dim intRow As Integer
Dim intCol As Integer
For intRow = 0 To intNumberOfRows - 1
For intCol = 0 To intNumberOfCols - 1
Try
tilTiles(intRow, intCol).Dispose()
Catch ex As Exception
End Try
Next
Next
End Sub
Clear clears the game board and discards the size selection. Lastly, add the Block structure:
Public Structure Block
Public intRow As Integer
Public intCol As Integer
Public Sub New(ByVal iRow As Integer, ByVal iCol As Integer)
Me.intRow = iRow
Me.intCol = iCol
End Sub
End Structure
Download the Code
The code to accompany this article is available. Please feel free to download it and use it for your own project.
Conclusion
Now that you know how to make a Tile Slider game and its logic involved, practice and try making your own.