VB:Tutorials:Building A Highscore Manager

From GPWiki

Files:GUITutorial_warn.gif The Game Programming Wiki has moved! Files:GUITutorial_warn.gif

The wiki is now hosted by GameDev.NET at wiki.gamedev.net. All gpwiki.org content has been moved to the new server.

However, the GPWiki forums are still active! Come say hello.

Tutorial by Nicholas Gorski GMan

This tutorial will show you the basics of creating a high score manager.

Creating the Class

Create a new Standard EXE. Insert a new class called Highscore_Manager. The first and most obvious function that we would need is a function that allows us to add scores to the high score table. But how do we save them? There is a function in Visual Basic called 'SaveSetting', which saves a setting in the registry. The function takes 4 parameters, the Application Name, Section, Key, and Value. Here is a visual reference:

Files:Highscore_Pic.gif

So our function will only need to take 3 parameters, Application Name, Player Name, and Score:

Public Function SaveScore(ByVal ApplicationName As String, ByVal PlayerName As String, ByVal Score As Long)
Call SaveSetting(ApplicationName, "Highscore", PlayerName, Str(Score))
End Function

I see many problems with this. One, however, is the fact that it doesn't test to see if the score is even high enough to make it onto the list. But in order to check if a score is valid, we need a way to load the high score list. This function will take five parameters, one is the number of scores in the list. The second is the default score if no entry is found, and the third is the default name. The fifth parameter is the Application Name, and the last parameter is a Boolean, which is used for sorting. If it is True, the scores will be sorted as the higher the score, the better (like a shooting game). False will sort them as the lower the score the better (such as golf). In order to save the scores in memory, we need two dynamic arrays, Scores and Names, along with their counting variable. At the top of the class, add:

Private Scores() As Long
Private Names() As String
Private NumberEntries As Long

Now make the load function:

Public Function LoadScores(ByVal NumberScores As Long, ByVal DefaultScore As Long, _
 ByVal DefaultName As String, ByVal ApplicationName As String, _
 Optional ByVal SortDirection As Boolean = True)
Dim i As Long, j As Long, t As Long, ts As String
 
'Make room for scores
NumberEntries = NumberScores
ReDim Scores(NumberScores) As Long
ReDim Names(NumberScores) As String
 
'Load them
For i = 0 To NumberScores
    Scores(i) = GetSetting(ApplicationName, "Highscore", i & "S", DefaultScore)
    Names(i) = GetSetting(ApplicationName, "Highscore", i & "N", DefaultName)
Next i
 
'Sort them
For i = 0 To NumberScores
    For j = 0 To NumberScores
        If SortDirection Then 'Higher the better
            If Scores(i) > Scores(j) Then
                t = Scores(i)
                ts = Names(i)
                Scores(i) = Scores(j)
                Names(i) = Names(j)
                Scores(j) = t
                Names(j) = ts
            End If
        Else
            If Scores(i) < Scores(j) Then
                t = Scores(i)
                ts = Names(i)
                Scores(i) = Scores(j)
                Names(i) = Names(j)
                Scores(j) = t
                Names(j) = ts
            End If
        End If
    Next j
Next i
End Function

However, you will notice that this function loads two settings from the registry. But we only saved one. We need to change the way we save. The procedure now needs to see whether the score is high enough, and if so, insert it into the proper place:

Public Function SaveScore(ByVal ApplicationName As String, ByVal PlayerName As String, _ 
 ByVal Score As Long, Optional ByVal SortDirection As Boolean = True) As Boolean
Dim i As Long, j As Long
Dim lT1 As Long, lT2 As Long, sT1 As String, sT2 As String
Dim lFound As Long
 
lFound = -1
 
For i = 0 To NumberEntries
    If SortDirection Then 'Higher the better
        If Score > Scores(i) Then
            SaveScore = True
            lFound = i
            Exit For
        End If
    Else
        If Score < Scores(i) Then
            SaveScore = True
            lFound = i
            Exit For
        End If
    End If
Next i
 
If lFound = -1 Then Exit Function
 
'Shift around scores and names
lT2 = Score
sT2 = PlayerName
For i = lFound To NumberEntries
    lT1 = Scores(i)
    sT1 = Names(i)
    Scores(i) = lT2
    Names(i) = sT2
    lT2 = lT1
    sT2 = sT1
Next i
 
'Save all scores
For i = 0 To NumberEntries
    Call SaveSetting(ApplicationName, "Highscore", i & "S", Scores(i))
    Call SaveSetting(ApplicationName, "Highscore", i & "N", Names(i))
Next i
End Function

Much bigger! We need two more functions to allow access to the arrays:

Public Function GetPlayerScore(ByVal Index As Long) As Long
On Error Resume Next
GetPlayerScore = Scores(Index)
End Function
 
Public Function GetPlayerName(ByVal Index As Long) As String
On Error Resume Next
GetPlayerName = Names(Index)
End Function

And one more to check whether a score is high enough to be on the list:

Public Function CheckScore(ByVal Score As Long, Optional ByVal SortDirection As Boolean = True) As Boolean
Dim i As Long, j As Long
 
For i = 0 To NumberEntries
    If SortDirection Then 'Higher the better
        If Score > Scores(i) Then
            CheckScore = True
            Exit Function
        End If
    Else
        If Score < Scores(i) Then
            CheckScore = True
            Exit Function
        End If
    End If
Next i
End Function

Now you have a basic high score list.

Done

You can download the source code here.

I suggest that you look up some encrytion methods. That will prevent people from creating false scores.