Creating a high score leaderboard

Lead Image © kudryashka, 123RF.com

Who's on First?

Learn how to save and track player high scores from one game to the next using lists and variables.

In many Scratch games, you want to create games that keep score and track high scores and rankings from one game to the next. In this article, I show you how to create a high score leaderboard for a game that will persist across sessions and display the rankings of the top three scores by name.

You can add this leaderboard to any game you have available. I'm going to use the Asteroid Blaster game that's included as one of the sample projects bundled with the Raspberry Pi version of Scratch [1]. I'm also going to incorporate the script from the "Stamping Numbers" article in the previous issue [2] that uses numbered costumes to display the score at the end of the game. Figure 1 shows the end result.

Figure 1: Asteroid Blaster leaderboard.

In Asteroid Blaster, the player has three lives to move a ship and shoot as many asteroids as possible. The player loses a life each time the ship collides with an asteroid. The game ends after the third collision. That's where I'm going to jump in and capture the scores to create a high score leaderboard. The game needs to track the top three scores, so each time the game ends, I need to check if the current score is higher than one of the top three scores. If the score is in the top three spots, I record the player's name and score.

To finish the programming, I want to display the current player's score and, after the top scores are evaluated, the top three high scores. Then I'll prompt the player to play another game.

Game Over, Check the Scores

I'm adding all my leaderboard scripts to a new sprite called Score, which will include costumes representing numbers, as I discussed in the previous article. Figure 2 shows the sprite's initialization script starting with the when I receive(Play Game) block. As you can see, you need to create and hide three variables named High Score 1, High Score 2, and High Score 3. The reason I'm using a Play Game broadcast instead of the usual when <green flag> clicked block is because the player will have an option to restart the game. I've also updated all the other scripts in the existing game to start on this broadcast message. The clear block removes the stamped score from the screen.

Figure 2: Initializing the Score sprite.

Figure 3 shows the script that runs after the player uses all three lives. It's triggered with a when I receive(Game Over), which replaces the say(Game Over) for(2) secs block in the Asteroid Blaster ship sprite. Without rewriting too much of the original script, you need to add a stop script block after the broadcast(Game Over) block; this prevents the game from restarting automatically.

Figure 3: Finding and displaying top-three scores.

The script requires two lists, Leaderboard Names and Leaderboard Scores, that are used to capture the leaders and their high scores. The Leaderboard Scores list needs to contain a number in each of the first three list items, or the evaluation that checks whether the score is greater than the current value will not work; with a non-number, the check will always evaluate to false and no player will ever be able to enter a high score.

I choose to add a zero to each of the first three items when I create the Leaderboard Scores list. This ensures that the score evaluations later in the script will work. You can either add the zeros directly to the list's stage monitor or use the add (0) to (Leaderboard Scores) block.

Scratch will remember the values of the lists and variables from one session to the next, so using this script, Scratch retains the name and scores from one session to the next, making it possible to track the high scores after the game has been closed and reopened in Scratch. You can even send your game to a friend and preserve the list values. This is why I do not include any blocks to initialize the starting values of the Leaderboard Scores and Leaderboard Names lists. After I set up the game, the only time I want the high scores to change is when a player earns a top-three score.

Next, you need to create the variable named Leaderboard Position to track each position in the lists as the script checks the current score to determine if it's a high score. The first thing the Game Over script does is stamp the player's current score using the broadcast(Show Current Score) block. That script is not pictured.

Next, I evaluate the score to see if it is greater than the lowest score in the list, which is item 3 in Leaderboard Scores. If the current score isn't higher, there's no reason to continue checking anything else, and it's an opportunity to display a custom message to the player.

If the score is large enough to be one of the top three scores, I set the Leaderboard Position variable to 1 because I want to start my evaluation with the first item in the list. The repeat(3) loop then evaluates whether or not score is greater than each item in the list. I'm only interested in capturing the top-three high scores ever, but if you wanted to have a bigger leaderboard, you could change the 3 to another number you find appropriate. I figure if the top-three spots are good enough for the Olympic podium, it's good enough for Asteroid Blaster.

In the Leaderboard Scores list, item 1 is the highest score and item 3 is the lowest. So, after the script determines that the player has a top-three score, my first check is to see if the score is higher than item 1. If the score is larger than the value in item 1, I know that the player earned a high score. The script can add the score into the first item of the Leaderboard Scores list.

If the score is not higher than the value in item 1 of the list, the script next checks the value in item 2 by using the Leaderboard Position variable to determine how many times the script has run through the repeat() loop to the list item number and thereby identify what list item is being evaluated. If the score is higher than the value in item 2, you also know that the player's score is either less than or equal to the top score. So, the script can add the score to item 2. If the score is less than the value in item 2, it moves onto item 3.

When you insert a new item into the list, the remaining values are moved to the next position in the list. At this point, the list will contain four items.

After you determine the high score the person earned, prompt the player for a name by telling them their rank. The nested join() () blocks uses a combination of text and variables to achieve this. The Leaderboard Position that you add to the join() () block not only tracks which item number in the Leaderboard Scores list is being evaluated, it represents the player's rank.

After the player enters a name, it's added to the Leaderboard Names list in the same position as the score was added to the Leaderboard Scores list. Now that you have an association, if you want to display the second highest score, for example, you would retrieve the item 2 values from both the Leaderboard Names and Leaderboard Scores lists. As long as you add, edit, or delete both lists at the same time, there will always be a clear relationship that you can rely on, and you'll see that relationship when it comes time to display the high scores.

The broadcast(Show Top Scores) and wait blocks used in Figure 3 will trigger the script in Figure 4.

Figure 4: Keeping track of top-three scores.

Show Top Scores

As shown in Figure 4, you combine the Leaderboard Names and Leaderboard Scores for each list item into a high score variable. Everything matches. For example, High Score 1 is assigned the values in the first items of Leaderboard Names and Leaderboard Scores. The scrip uses the show variable() block to display a monitor on the stage with the new values for each of the high score variables. Figure 1 shows what this looks like at the end of the game.

Being able to control the display of the variables with a block enables you to show and hide the variable value relatively easily. If you were to allow the variable monitors to be displayed continually, the stage would become cluttered.

You can not position the stage monitor via the script; however, you can drag the monitors around the stage to position them. Then, each time you display the variable, it will show up where you last positioned it.

Although it's possible to show and hide each variable's stage monitor, lists do not have equivalent show or hide blocks. To display the list monitors on the stage, you would need to go to the Variables palette and select the list you want to show or hide.

The final few blocks of the script in Figure 4 prompt the player to start another game. Pressing y will restart the game via the Play Game broadcast. Any other input will end the game. To use the Play Game broadcast to replay the game in Asteroid Blaster, you'll need to change the scripts for the ship, laser, and asteroids to start when each script receives the broadcast.

Buy Raspberry Pi Geek

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Custom stamping game scores with costume numbers

    Add style to game score displays with stamp blocks and costumes.

  • Using graphical effects to distort a picture

    In this guessing game, graphic effects distort sprite costumes while the player tries to guess the animal shape. The game is creatively scored based on how much the shape is distorted.

  • Creating a multiplayer quick-reaction game

    The quick-reaction game provides an introduction to building simple circuits with the Raspberry Pi and controlling those circuits with ScratchGPIO, an advanced version of Scratch.

  • Synchronizing with broadcasts

    This article draws inspiration from the popular Pokémon Go app to recreate a sprite hunting game in Scratch. The project explores synchronization and randomness as the player explores various backdrops in search of sprites.

  • Power to You

    Small-board computers (SBCs) are getting more and more powerful. The Raspberry Pi 3 (RPi3), which just came out in February of this year, is a case in point. This latest in the Rasp Pi line now has four cores running at 1200MHz with 1GB of RAM and on-board WiFi and Bluetooth. If you need even more power in a small computer, however, you are not left wanting. In this issue, we look at three SBCs with more cores, more memory, more ports, and more possibilities.