Creating your own Hidden Object game with VB.NET Part 2 - Playing the Game

Introduction

If you enjoyed (and I hope that you did) the previous installment in this article series, you will definitely enjoy this part! Here, we will concentrate on the gameplay. We will introduce new functionalities to our project that will enable us to have a working game.

Design

First, we have to add a few controls and forms to our existing project. Let us continue where we left off and add the following controls with their associated properties to the form called frmJJM :

ControlPropertySetting
PictureBox Name picJJMInfo
  BackColor Black
  Dock Fill
  Location ( If necessary ) 0, 0
  Size ( If necessary ) 972, 38
PictureBox Name picJJMCountDown
  BackColor Black
  Dock Right
  Location 730, 0
  Size 242, 38
Timer Name tmrJJM
  Interval 1000 - One Second
Timer Name tmrWait
  Interval 2000 - Two Seconds

While we are in design mode, let's add a new form to be used as a Summary Form, which will display our points and other details, after all the objects have been found.

Add a new form by clicking on Project, Add Windows Form. Give it a name of frmSummary, and add the following controls and properties to it:

ControlPropertySetting
frmSummary BackColor ForestGreen
  ShowInTaskbar False
  Size 634, 460
  StartPosition CenterScreen
Panel Name pnlNext
  BackColor Black
  Dock Bottom
  Location 0, 412
  Size 634, 48
PictureBox Name picSummary
  BackColor Black
  Dock Fill
Button Name btnJJMExit
  Dock Right
  FlatStyle System
  Text Exit

All the design work is done, for now. What we need to do next is to make the game an actual game. In the first installment of this article series, we simply randomly put all of the objects on the screen and enabled the user to click on them; that was it. There was no score, no time limit, and most importantly; no list of items to find! Let's now add this logic.

Displaying a List of Items

As you know, there is a total of 20 objects that need to be found in this game; technically that is incorrect. Why? Well, because there are 4 birds, 2 earrings, and two shoes that need to be counted as one. A quick math calculation will bring us to a grand total of only fifteen hidden items. Hidden object games regularly do this too. They have more than one object or task that makes only one item. Does this make sense? Don't stress if it doesn't; let's have a look. Afterwards you'll see what we have done.

To get a list of items displayed, we need a way to store the items. I chose to use an array, but these games usually have a file from where they read these objects.

Declare the following arrays in the General Section of frmJJM.

    'Original items to be found
    Private arrItems() As String = {"2 shoes", "rhino", "key", "ingredient for wine", "stradivarius", "upside-down", "provides news", "4 birds", "king of the jungle", "2 earrings", "invented by Thomas Crapper", "writes with graphite", "makes mobile calls", "storage place for money", "zeppelin"}
    'FOUND items
    Private arrItems2() As String = {"2 shoes - FOUND", "rhino - FOUND", "key - FOUND", "ingredient for wine - FOUND", "stradivarius - FOUND", "upside-down - FOUND", "provides news - FOUND", "4 birds - FOUND", "king of the jungle - FOUND", "2 earrings - FOUND", "invented by Thomas Crapper - FOUND", "writes with graphite - FOUND", "makes mobile calls - FOUND", "storage place for money - FOUND", "zeppelin - FOUND"}

The first array simply holds the actual items we need to find. The second array will be displaying "FOUND" after each item was found. Now, we have to print these items on screen. Add the following Sub Procedure to your form :

    'Displays Items on screen
    Private Sub picJJMItems_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles picJJMItems.Paint
        Dim brJJMItems As Brush = Brushes.ForestGreen 'Brush for Words

        Dim fntJJMFont As New Font("Comic Sans MS", 8, FontStyle.Bold) 'Font Style
        Dim x_Location, y_Location As Single 'Where to Write

        Dim i As Integer 'Loop Counter

        x_Location = 10 'Horizontal Starting Point
        y_Location = 0 'Vertical Starting Point

        For i = 0 To 2 'First three Items
            e.Graphics.DrawString(arrItems(i) & Environment.NewLine, fntJJMFont, brJJMItems, _
                x_Location, _
                y_Location)
            y_Location += 20 'Shift Down
        Next

        x_Location += 200 'Shift Right
        y_Location = 0

        For i = 3 To 5 'Second Three Items
            e.Graphics.DrawString(arrItems(i) & Environment.NewLine, fntJJMFont, brJJMItems, _
                x_Location, _
                y_Location)
            y_Location += 20
        Next

        x_Location += 200
        y_Location = 0

        For i = 6 To 8 'Third Column
            e.Graphics.DrawString(arrItems(i) & Environment.NewLine, fntJJMFont, brJJMItems, _
                x_Location, _
                y_Location)
            y_Location += 20
        Next

        x_Location += 200
        y_Location = 0

        For i = 9 To 11 'Fourth Column
            e.Graphics.DrawString(arrItems(i) & Environment.NewLine, fntJJMFont, brJJMItems, _
                x_Location, _
                y_Location)
            y_Location += 20
        Next

        x_Location += 220
        y_Location = 0

        For i = 12 To 14 'Fifth Column
            e.Graphics.DrawString(arrItems(i) & Environment.NewLine, fntJJMFont, brJJMItems, _
                x_Location, _
                y_Location)
            y_Location += 20
        Next

    End Sub

Because there are fifteen items, I decided to list five columns of three items each. If you were to run your program now, you would see the list displayed as in the following picture:

Items to be found
Figure 1 - Items to be found

Creating your own Hidden Object game with VB.NET Part 2 - Playing the Game - Page 2

The Trick Now is to Update This

The trick now is to update this screen each time an item is found. We'll do that shortly. What we also have to remember here is the fact that we currently have 2 shoes, 2 earrings and 4 birds. Because they count as one item, we need to create counter variables to keep track of how many shoes or birds or earrings have been found. Let us create these variables in the General Section.

    Private intShoeCounter As Integer = 2 'Total Shoes
    Private intBirdCounter As Integer = 4 'Total Birds
    Private intEarringCounter As Integer = 2 'Total Earrings

Besides these, we need an overall Item counter as well. This is so that we can keep track of how many items were found. Declare the following variables

    Private intItemsFound As Integer 'Total Items Found
    Private intRemain As Integer = 15 'Total Items

While we're at it. Let's add a variable to keep Score, based on the items found.

    Private intScore As Integer 'Score

Now, let's edit the picItems_Click to reflect all these changes, and be able to have a score

    Private Sub picItems_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim pic As PictureBox = DirectCast(sender, PictureBox)

        If sender.Equals(picItems(0)) Or sender.Equals(picItems(1)) Then ' 2 shoes
            intShoeCounter -= 1
            If intShoeCounter = 1 Then
                arrItems(0) = "ONE shoe LEFT"
                intScore += 20
                intItemsFound += 1
                picJJMInfo.Invalidate()
            ElseIf intShoeCounter = 0 Then
                intShoeCounter = 0
                arrItems(0) = arrItems2(0)
                intScore += 20
                intItemsFound += 1
                intRemain -= 1
                picJJMInfo.Invalidate()
            End If
            pic.Visible = False
            picJJMItems.Invalidate()

        ElseIf sender.Equals(picItems(2)) Then 'rhino
            arrItems(1) = arrItems2(1)
            pic.Visible = False
            picJJMItems.Invalidate()
            intScore += 20
            intItemsFound += 1
            intRemain -= 1
            picJJMInfo.Invalidate()

        ElseIf sender.Equals(picItems(3)) Then 'key
            arrItems(2) = arrItems2(2)
            picItems(3).Visible = False
            picJJMItems.Invalidate()
            intScore += 20
            intItemsFound += 1
            intRemain -= 1
            picJJMInfo.Invalidate()

        ElseIf sender.Equals(picItems(4)) Then 'grapes
            arrItems(3) = arrItems2(3)
            pic.Visible = False
            picJJMItems.Invalidate()
            intScore += 20
            intItemsFound += 1
            intRemain -= 1
            picJJMInfo.Invalidate()

        ElseIf sender.Equals(picItems(5)) Then 'violin
            arrItems(4) = arrItems2(4)
            pic.Visible = False
            picJJMItems.Invalidate()
            intScore += 20
            intItemsFound += 1
            intRemain -= 1
            picJJMInfo.Invalidate()

        ElseIf sender.Equals(picItems(6)) Then 'upsidedown
            arrItems(5) = arrItems2(5)
            pic.Visible = False
            picJJMItems.Invalidate()
            intScore += 20
            intItemsFound += 1
            intRemain -= 1
            picJJMInfo.Invalidate()

        ElseIf sender.Equals(picItems(7)) Then 'newspaper
            arrItems(6) = arrItems2(6)
            pic.Visible = False
            picJJMItems.Invalidate()
            intScore += 20
            intItemsFound += 1
            intRemain -= 1
            picJJMInfo.Invalidate()

        ElseIf sender.Equals(picItems(8)) Or sender.Equals(picItems(9)) Or sender.Equals(picItems(10)) _
            Or sender.Equals(picItems(11)) Then '4 birds

            intBirdCounter -= 1

            If intBirdCounter = 3 Then
                arrItems(7) = "THREE birds LEFT"
                intScore += 20
                intItemsFound += 1
                picJJMInfo.Invalidate()
            ElseIf intBirdCounter = 2 Then
                arrItems(7) = "TWO birds LEFT"
                intScore += 20
                intItemsFound += 1
                picJJMInfo.Invalidate()
            ElseIf intBirdCounter = 1 Then
                arrItems(7) = "ONE bird LEFT"
                intScore += 20
                intItemsFound += 1
                picJJMInfo.Invalidate()
            ElseIf intBirdCounter = 0 Then
                intBirdCounter = 0
                arrItems(7) = arrItems2(7)
                intScore += 20
                intItemsFound += 1
                intRemain -= 1
                picJJMInfo.Invalidate()
            End If

            pic.Visible = False
            picJJMItems.Invalidate()

        ElseIf sender.Equals(picItems(12)) Then 'lion
            arrItems(8) = arrItems2(8)
            pic.Visible = False
            picJJMItems.Invalidate()
            intScore += 20
            intItemsFound += 1
            intRemain -= 1
            picJJMInfo.Invalidate()

        ElseIf sender.Equals(picItems(13)) Or sender.Equals(picItems(14)) Then '2 earrings
            intEarringCounter -= 1
            If intEarringCounter = 1 Then
                arrItems(9) = "ONE earring LEFT"
                intScore += 20
                intItemsFound += 1
                picJJMInfo.Invalidate()
            ElseIf intEarringCounter = 0 Then
                intEarringCounter = 0
                arrItems(9) = arrItems2(9)
                intScore += 20
                intItemsFound += 1
                intRemain -= 1
                picJJMInfo.Invalidate()

            End If
            pic.Visible = False
            picJJMItems.Invalidate()

        ElseIf sender.Equals(picItems(15)) Then 'toilet
            arrItems(10) = arrItems2(10)
            pic.Visible = False
            intScore += 20
            intItemsFound += 1
            picJJMItems.Invalidate()
            intRemain -= 1
            picJJMInfo.Invalidate()

        ElseIf sender.Equals(picItems(16)) Then 'pencil
            arrItems(11) = arrItems2(11)
            pic.Visible = False
            picJJMItems.Invalidate()
            intScore += 20
            intItemsFound += 1
            intRemain -= 1
            picJJMInfo.Invalidate()

        ElseIf sender.Equals(picItems(17)) Then 'cellphone
            arrItems(12) = arrItems2(12)
            pic.Visible = False
            picJJMItems.Invalidate()
            intScore += 20
            intItemsFound += 1
            intRemain -= 1
            picJJMInfo.Invalidate()

        ElseIf sender.Equals(picItems(18)) Then 'wallet
            arrItems(13) = arrItems2(13)
            pic.Visible = False
            picJJMItems.Invalidate()
            intScore += 20
            intItemsFound += 1
            intRemain -= 1
            picJJMInfo.Invalidate()

        ElseIf sender.Equals(picItems(19)) Then 'zeppelin
            arrItems(14) = arrItems2(14)
            pic.Visible = False
            picJJMItems.Invalidate()
            intScore += 20
            intItemsFound += 1
            intRemain -= 1
            picJJMInfo.Invalidate()
        End If
    End Sub

The above code is still quite straightforward. We simply added onto what we already had. We incremented the score each time an item was found. We Incremented the ItemsFound variable, and decremented the intRemain variable so that we will know when all of the items have been found. You will notice that we Invalidate picJJMInfo here as well, because that is where our Score is, and the number of items. We need to add its Paint event:

    Private Sub picJJMInfo_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles picJJMInfo.Paint
        Dim objBackBrush As Brush = Brushes.ForestGreen
        Dim objFont As New Font("Comic Sans MS", 14, FontStyle.Bold)
        Dim x_Location, y_Location As Single

        x_Location = 5
        y_Location = 5

        e.Graphics.DrawString("Score: " & intScore.ToString & " Remaining Items: " & intRemain.ToString, objFont, objBackBrush, _
                x_Location, _
                y_Location)
    End Sub

When run, we will see a Score as well as how many items are left, as in Figure 2. Also, do not forget to look at the Items screen, where you will see the word "FOUND" next to each found item, as displayed in Figure 3

Score and Items remaining
Figure 2 - Score and Items remaining

Items found
Figure 3 - Items found

Creating your own Hidden Object game with VB.NET Part 2 - Playing the Game - Page 3

Adding a Countdown

With this game I want to give the player a whole five minutes to find all of the items. It may sound ridiculous, but, you never know how long a person can struggle to find one item. Let's create two variables again, inside the General Section:

    Private timeEnd As DateTime 'Calculates Ending Time
    Private timeDiff As TimeSpan 'Difference Between Start and End Times

Add the following to the Form_Load event :

        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

        tmrWait.Start() 'Start Temp Timer

This calculates how much time we have - in this case we have 5 minutes.

Add the tmrWait_Tick event:

    Private Sub tmrWait_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrWait.Tick
        tmrJJM.Start()
        tmrWait.Stop()
    End Sub

All this event does is to ensure all of the objects have loaded properly before starting the Countdown timer, which looks like :

    Private Sub tmrJJM_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles tmrJJM.Tick
        picJJMCountDown.Refresh() 'Repaint
        Dim objBackBrush As Brush = Brushes.ForestGreen 'Green ForeColor
        Dim objFont As New Font("Comic Sans MS", 12, FontStyle.Bold) 'Font Style

        Dim x_Location, y_Location As Single 'X & Y Locations

        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)

        x_Location = 5
        y_Location = 5

        strFinalOutput = "Time Left: " & output.ToString().Substring(3) 'Concatenates Time

        picJJMCountDown.CreateGraphics().DrawString(strFinalOutput, objFont, objBackBrush, _
                x_Location, _
                y_Location) 'Draw the String

    End Sub

Run your Game now. Do you see the Time? Yes, it should look like Figure 4

Time Left
Figure 4 - Time Left

Displaying a Summary of Results

The last stage in this article is to display a summary of results to the player. The purpose of this is to show the score, calculate a time bonus and more (which will be handled in the third and final part of this series )

Create the following Sub procedure:

    'Displays Final Results
    Private Sub DisplaySummary()

        Dim strSummary As String 'Summary String

        'Calculate Bonus For Minutes and Seconds Left
        If timeDiff.Minutes > 0 Then
            intTimeBonus = timeDiff.Minutes * 50

        End If

        If timeDiff.Seconds > 0 Then
            intTimeBonus += timeDiff.Minutes * 20

        End If


        intScore += intTimeBonus 'Add To Score

        'Compose String For Output
        strSummary = "Jungle Jive Mystery Summary" & Environment.NewLine & Environment.NewLine & _
            "Stage 1 - Amazon" & Environment.NewLine & Environment.NewLine & _
            "Items Found: " & intItemsFound.ToString & Environment.NewLine & Environment.NewLine & _
            "TIME BONUS: " & intTimeBonus.ToString & Environment.NewLine & Environment.NewLine & _
            "SCORE: " & intScore.ToString

        Dim FS As New frmSummary(strSummary, intScore)
        FS.Show() 'Show Summary Form

    End Sub

We need to display the summary in two cases:

  1. When all items have been found
  2. When the time has expired

Edit the picItems_Click event to include the call to the above sub. You can add this just before End Sub:

        If intRemain = 0 Then 'No More Items              DisplaySummary()          End If

Lastly, edit the tmrJJM_Tick event to also include a call to DisplaySummary. You can also add it before the end of the sub :

        If (timeDiff.Ticks < 0) Then 'If Time is Up

            tmrJJM.Stop()
            MessageBox.Show("Time's UP!!")
            DisplaySummary()
        End If

Open the Designer.vb file for frmSummary and add the next two variables inside its Constructor:

 Public Sub New(ByVal sString As String, ByVal iScore As Integer)
Me.New()

strSumm = sString
intScore = iScore


End Sub

Add the following to frmSummary's code:

Public Class frmSummary
    Private strSumm As String
    Private intScore As String

    Private Sub btnJJMExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnJJMExit.Click
        Application.Exit()
    End Sub

    Private Sub picSummary_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles picSummary.Paint
        Dim brJJMItems As Brush = Brushes.ForestGreen

        Dim fntJJMFont As New Font("Comic Sans MS", 12, FontStyle.Bold)
        Dim x_Location, y_Location As Single

        x_Location = 10
        y_Location = 20

        e.Graphics.DrawString(strSumm, fntJJMFont, brJJMItems, _
        x_Location, _
        y_Location) 'Draw whatever String Was Supplied From frmJJM
    End Sub

End Class

Run your completed game now, and find all the items. Once everything has been found, you'll see the Summary screen, as in Figure 5

Summary Screen
Figure 5 - Summary Screen

Conclusion

I hope you have enjoyed this article. In the last part, we will Add a Hint functionality, as well as play around with setting the correct screen resolution for our game, and resetting it. We will also finalize the game by adding an introduction and conclusion screen - as well as a BONUS. We still have lots to do, so stay tuned! Cheers!



Related Articles

Downloads

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

  • Live Event Date: December 18, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this upcoming webcast …

Most Popular Programming Stories

More for Developers

RSS Feeds