В точке (2) директива форматирования строки приказывает Python вставить запятые при преобразовании числового значения в строку — например, чтобы вместо 1000000 выводилась строка 1,000,000. Теперь при запуске игры всегда будет отображаться аккуратно отформатированный, округленный счет (рис. 14.3).
Каждый игрок желает превзойти предыдущий рекорд игры, поэтому мы будем отслеживать и выводить рекорды, чтобы у игрока была ясная цель. Рекорды будут храниться в классе GameStats:
game_stats.py
def __init__(self, ai_settings):
...
. .# Рекорд не должен сбрасываться.
. .self.high_score = 0
Так как рекорд не должен сбрасываться при повторном запуске, значение high_score инициализируется в __init__(), а не в reset_stats().
Теперь изменим класс Scoreboard для отображения рекорда. Начнем с метода __init__():
scoreboard.py
def __init__(self, ai_settings, screen, stats):
...
. . . .# Подготовка изображений счетов.
self.prep_score()
(1) . . . .self.prep_high_score()
Рекорд должен отображаться отдельно от текущего счета, поэтому для подготовки его изображения понадобится новый метод prep_high_score():
scoreboard.py
def prep_high_score(self):
. ."""Преобразует рекордный счет в графическое изображение."""
(1) . .high_score = int(round(self.stats.high_score, -1))
(2) . . . .high_score_str = "{:,}".format(high_score)
(3) . . . .self.high_score_image = self.font.render(high_score_str, True,
. . . . . .self.text_color, self.ai_settings.bg_color)
. . . . . .
. . . .# Рекорд выравнивается по центру верхней стороны.
. . . .self.high_score_rect = self.high_score_image.get_rect()
(4) . . . .self.high_score_rect.centerx = self.screen_rect.centerx
(5) . . self.high_score_rect.top = self.score_rect.top
Рекорд округляется до десятков (1) и форматируется с запятыми (2). Затем для рекорда строится графическое изображение (3), выполняется горизонтальное выравнивание прямоугольника по центру экрана (4), а атрибут top прямоугольника приводится в соответствие с верхней стороной изображения счета (5).
Теперь метод show_score() выводит текущий счет в правом верхнем углу, а рекорд — в центре верхней стороны:
scoreboard.py
def show_score(self):
"""Выводит счет на экран."""
self.screen.blit(self.score_image, self.score_rect)
. .self.screen.blit(self.high_score_image, self.high_score_rect)
Для обновления рекорда в файл game_functions.py добавляется новая функция check_high_score():
game_functions.py
def check_high_score(stats, sb):
. ."""Проверяет, появился ли новый рекорд."""
(1) . .if stats.score > stats.high_score:
. . . .stats.high_score = stats.score
. . . .sb.prep_high_score()
Рис. 14.4. Рекордный счет выводится в середине экрана
Функция check_high_score() получает два параметра, stats и sb. Параметр stats используется для проверки текущего счета и рекорда, а параметр sb необходим для изменения изображения рекорда при необходимости. В точке (1) программа сравнивает текущий счет с рекордом. Если текущий счет выше, мы обновляем значение high_score и вызываем prep_high_score() для обновления изображения рекорда.
Функция check_high_score() должна вызываться при каждом попадании в пришельца после обновления счета в check_bullet_alien_collisions():
game_functions.py
def check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship,
aliens, bullets):
...
if collisions:
for aliens in collisions.values():
stats.score += ai_settings.alien_points * len(aliens)
sb.prep_score()
. . . .check_high_score(stats, sb)
...
Когда вы впервые играете в Alien Invasion, текущий счет одновременно будет наивысшим, поэтому он будет отображаться и как текущий счет, и как рекорд. Но в начале второй игры ваш предыдущий рекорд должен отображаться в середине, а текущий счет справа, как показано на рис. 14.4.
Чтобы в игре выводился текущий уровень, сначала в класс GameStats следует включить атрибут для его представления. Чтобы уровень сбрасывался в начале каждой игры, инициализируйте его в reset_stats():
game_stats.py
def reset_stats(self):
. ."""Инициализирует статистику, изменяющуюся в ходе игры."""
. .self.ships_left = self.ai_settings.ship_limit
. .self.score = 0
. .self.level = 1
Чтобы класс Scoreboard выводил текущий уровень (сразу же под текущим счетом), мы вызываем новый метод prep_level() из __init__():
scoreboard.py
def __init__(self, ai_settings, screen, stats):
...
# Подготовка изображений счетов.
self.prep_score()
self.prep_high_score()
. .self.prep_level()
Метод prep_level() выглядит так:
scoreboard.py
. .def prep_level(self):
. . . ."""Преобразует уровень в графическое изображение."""
(1) . . . .self.level_image = self.font.render(str(self.stats.level), True,
. . . . . . . .self.text_color, self.ai_settings.bg_color)
. .
. . . .# Уровень выводится под текущим счетом.
. . . .self.level_rect = self.level_image.get_rect()
(2) . . . .self.level_rect.right = self.score_rect.right
(3) . . . .self.level_rect.top = self.score_rect.bottom + 10