d) High scores
Every game needs a high score list! Doesn’t it?.. Ok, but this game does..
See file “3 - high scores.bmx”
The first thing we need to do is add a field to our game type to keep track of the current score and increase it every time we detect a collision between a bullet and an enemy. That’s so simple I’m not even going to cover the code here. However, we need to display the current score to the user and at the end of the game, we need to submit it to the high score list.
Printing the score to screen
For that we’re going to use a framework function in our games Draw method GuiDrawText.
GuiDrawText( playerScore, 350, 10 )
playerScore is the integer field we added to our game type and while GuiDrawText expects a string, Blitzmax will handle the conversion for us. The other parameters are the screen coordinates.
There’s also an optional fourth parameter; “font:String”. That will specify the actual font name we want to draw the text with. When the GUI was loaded the configuration file had a list of fonts to load. In our case we loaded just one “neuropol18.fnt”, so specifying the name is pointless. Whenever the fourth parameter left empty, the first font on the list is used.
Submitting the high score
At the end of the game we will submit the score regardless of high or low it really is. There’s no sorting for our application to worry about as we’ll leave all that to the framework. The end of the game is clearly the point where the FadeOutComplete method is called, so lets submit the score in there..
AddHighScore( 0, playerScore )
It’s that easy. The framework supports “high score groups” so that your game may have seperate leaderboards for different types of gameplay modes, or different achievements, so the first parameter is which high score group we want to use. As our game is very simple it’s only using one (the first) group.
AddHighScore will return an integer value that relates to where the score was inserted in the list. A value of -1 means the score wasn’t high enough to make the list and 0 is the highest position. You can use the returned value to work out if you should congratulate (or berate!) the user for their performance.
That covers the changes we had to make to our game type.
Displaying the high scores
This part is slightly more complex and heavily invloves the GUI system.
The main menu resource file (Media/mainmenuResources.txt) contains the line:
WINDOW Media/highscoresform.txt
Which asks the framework to load that GUI window. If you open up Media/highscoresform.txt you’ll see at the very top of the file;
name=highscores
With all other resources we define them as “TYPE name = file” , but GUI windows are different in that their name is defined in their own file.
Further into Media/highscoresform.txt, there are lots of <label> controls defined, each one has a unique name (score1 to score10). In order to display the high scores we are simply going to dynamically set the caption text for each one of these label controls.
We’ll add the caption setting code to the mainmenu Update function, at the point just before the high score window is shown:
Else If ( GuiButtonHit( “highscores” ) )
For Local t:Int = 0 To 9
Local score$ = GetHighScoreName( 0, t ) + ” …. ” + GetHighScoreValue( 0, t )
GuiSetControlCaptionText( “highscores”, “score” + (t + 1), score$ )
Next
PlaySoundByName( “swish” )
GuiHideWindow( “menu” )
GuiShowWindow( “highscores” )
We have a loop of 10 high score values and for each one we build a string using two functions GetHighScoreName, and GetHighScoreValue. We then use GuiSetControlCaptionText to change the text in our form named “highscores” on our control named “score” + (t + 1). The other code is unchanged and it plays a sound effect, hides the main menu and shows the highscore window.
Setting the players name
We have a log-in screen that contains an edit line control. What we need is to take the name from the control and use it in the app. To do that we will use another Gui method; GuiGetControlCaptionText, along with the SetUserName function. I’ve added this line to the other code that runs in response to the “start” button being hit.
SetUserName( GuiGetControlCaptionText( “login”, “login_name” ) )
The framework allows much more complex player account management but we’ll cover that in a more advanced tutorial in the future.
Initialising the high scores
We can’t add high scores to the list unless the list has been initialised. In some cases the high scores will be loaded from our INI settings file, but often they will need setting to default values. Here’s how we do that, by adding this line to our application start up code (right before RunApp)..
AddDummyHighScores( 0, “matt”, 1000, 40, 10 )
The first parameter is the high score group, then there’s the name we’ll use, the maximum score, the score decrement and the number of scores we want. Therefore, that call will give us 10 high scores in high score group 0, all by “matt” (whoever he is). The top score will be 1000, second will be 960, third 920, 880 etc.
The dummy high scores will not overwrite your legitimate scores if they are retrieved from an INI settings file, so let’s allow our application to save its setting and high scores!
Using an INI settings file
Settings files are useful for storing all kinds of values; from user options, player accounts and of course, high scores. Many settings are saved and loaded automatically for us by the framework and it also gives us simple methods to save and load our own.
In order to give the application the right to use an INI file, we need to tell it the filename when we call InitApp. So far we’ve left the fourth parameter blank which means all our settings have been lost each time we quit. So lets give it a filename..
InitApp( 800, 600, 32, “gamedata.txt” )
Now when we run and exit the app, gamedata.txt will automatically contain all our preferences and high scores - take a look! In more advanced tutorials we’ll cover setting and retrieving our own values as well encrypting the INI file so it’s not human readable - we don’t want our players cheating now do we?
And that’s it for adding high scores and we’re almost there with our first game!
On to: Adding an intro
