The highscore module provides a set of classes to make gathering and displaying high score information relatively simple. Classic Grand Champion, High Score #1-#4 style high score tables can be created with just a few lines. With a few more lines you can gather more sophisticated high scores, such as loop champion or similar.
While InitialEntryMode prompts the player for their initials, most developers will want to use EntrySequenceManager, which coordinates the display of a series of InitialEntryMode s. EntrySequenceManager is designed to be used with a subclass of HighScoreLogic, which enables the developer to take advantage of these classes while using completely custom logic to determine what initials need to be prompted for. CategoryLogic, is a powerful HighScoreLogic subclass that most developers will find suitable for implementing modern high score functionality.
Finally, generate_highscore_frames() can help to quickly create a traditional high score display.
In your GameController subclass’s setup method, configure the categories you wish to track scores for. The categories are used each time the game ends, as we’ll see in the next step. In this case we’ll setup two categories: a ‘classic’ category for the traditional Grand Champion and high scores 1-4, and a more modern ‘loop champ’ category. We set score_for_player to tell the category how to obtain that particular score value. Note that because the loop champ only has one title, only the highest loop score will be saved. The number of titles is used to determine how many scores are saved.
def setup(self):
self.highscore_categories = []
cat = highscore.HighScoreCategory()
cat.game_data_key = 'ClassicHighScoreData'
cat.titles = ['Grand Champion', 'High Score 1', ... , `High Score 4`]
self.highscore_categories.append(cat)
cat = highscore.HighScoreCategory()
cat.game_data_key = 'LoopsHighScoreData'
cat.titles = ['Loop Champ']
cat.score_for_player = lambda category, player: player.loops
cat.score_suffix_singular = ' loop'
cat.score_suffix_plural = ' loops'
self.highscore_categories.append(cat)
for category in self.highscore_categories:
category.load_from_game(self)
We use EntrySequenceManager to manage the high score prompting process once the game has finished. We instantiate it like a normal mode, set the finished handler and logic, and then add it to the mode queue:
def game_ended(self):
seq_manager = highscore.EntrySequenceManager(game=self, priority=2)
seq_manager.finished_handler = self.highscore_entry_finished
seq_manager.logic = highscore.CategoryLogic(game=self, categories=self.highscore_categories)
self.modes.add(seq_manager)
Finally, we write the finished handler to remove the sequence manager and add the attract mode to prepare for starting a new game:
def highscore_entry_finished(self, mode):
self.modes.remove(mode)
self.start_attract_mode()
An attract mode that displays the high scores might look like this:
class Attract(game.Mode):
def mode_started(self):
script = [{'seconds':2.0, 'layer':None}]
for frame in highscore.generate_highscore_frames(self.game.highscore_categories):
layer = dmd.FrameLayer(frame=frame)
script.append({'seconds':2.0, 'layer':layer})
self.layer = dmd.ScriptedLayer(width=128, height=32, script=script)
That the None layer allows the score display to be seen (as it is beneath the attract mode) for one period of the script.
Default scores and initials should be set using the game data template (the template_filename argument to procgame.game.GameController.load_game_data()). The key must match the HighScoreCategory.game_data_key value. Example:
ClassicHighScores:
- {inits: GSS, score: 5000000}
- {inits: ASP, score: 4000000}
- {inits: JRP, score: 3000000}
- {inits: JAG, score: 2000000}
- {inits: JTW, score: 1000000}
LoopsHighScoreData:
- {inits: GSS, score: 5}
Subclass of HighScoreLogic. Implements a variable number of scoreboards using categories.
categories is a list of HighScoreCategory instances which will be checked for qualifying high scores.
Used by HighScoreLogic subclasses’ HighScoreLogic.prompts() methods to communicate which scores need to be prompted for.
Object that will be used to identify this prompt when HighScoreLogic.store_initials() is called.
String or array of strings to be displayed on the left side of InitialEntryMode.
String or array of strings to be displayed on the right side of InitialEntryMode.
Model class.
score, inits and date are persisted via the dictionary with from_dict() and to_dict(). The remaining attributes are used to maintain state.
String date representation of this score, using time.asctime().
Populate the high score value from a dictionary. Requires score and inits keys, may include date.
Player’s initials.
Object value used to uniquely identify this score.
Player’s name, such as Player 1.
Numeric high score value.
Title for this score, such as Grand Champion.
Returns a dictionary representation of this high score, including score, inits, and date.
Key to this high score category’s data within game.GameController.game_data.
Loads scores from game using game_data_key.
Saves scores to game using game_data_key.
Method used to fetch the high score score value for a given Player. The default value is:
lambda player: player.score
Plural suffix to append to string representations of high scores in this category, such as points. Used by generate_highscore_frames().
Singular suffix to append to string representations of high scores in this category, such as point. Used by generate_highscore_frames().
List of HighScore objects for this category. Populated by load_from_game().
There must be a title for each high score slot desired for this category.
Interface used by EntrySequenceManager to abstract away the details of high score entry and storage.
Return a list of EntryPrompt objects to be presented to the player, in order.
Called by EntrySequenceManager to store the entered initials.
Mode that prompts the player for their initials.
left_text and right_text are strings or arrays to be displayed at the left and right corners of the display. If they are arrays they will be rotated.
entered_handler is called once the initials have been confirmed.
This mode does not remove itself; this should be done in entered_handler.
Method taking two parameters: mode and inits.
A Mode subclass that manages the presentation of InitialEntryMode in order to prompt the player(s) for new high scores.
The logic attribute should be set to an instance of HighScoreLogic, which is used to customize the behavior of the sequence manager. The behavior of this class can be modified by supplying different subclasses of HighScoreLogic.
This mode does not remove itself from the mode queue. Set finished_handler to a method to call once the sequence is completed. The handler will be called immediately (once this mode is added to the mode queue) if there are no high scores to be entered.
Subclasses can override this to supply their own entry handler.
Method taking one parameter, the mode (this object instance).
Set this attribute to an instance of HighScoreLogic.
To be called externally if using the ready_handler, once that handler has been called. Presents the initials entry mode.
Method taking two objects: this class instance and the EntryPrompt to be shown next. The implementor must call prompt() in order to present the initials entry mode, otherwise the sequence will not proceed. If this attribute is not set then initials entry mode will be shown immediately. This allows for special displays or interaction before each initials prompt.
Utility function that returns a sequence of Frame objects describing the current high scores in each of the categories supplied. categories should be a list of HighScoreCategory objects.