В точке (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