Вывод уровня
Чтобы в игре выводился текущий уровень, сначала в класс 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
Метод prep_level() создает изображение на базе значения, хранящегося в stats.level (1) , и приводит атрибут right изображения в соответствие с атрибутом right счета (2). Затем атрибут top сдвигается на 10 пикселов ниже нижнего края изображения текущего счета, чтобы между счетом и уровнем оставался пустой интервал (3).
В метод 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)
. .self.screen.blit(self.level_image, self.level_rect)
Добавленная строка выводит на экран изображение, представляющее уровень.
Увеличение stats.level и обновление изображения уровня выполняются в check_bullet_alien_collisions():
game_functions.py
def check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship,
aliens, bullets):
...
if len(aliens) == 0:
. . . .# Если весь флот уничтожен, начинается следующий уровень.
bullets.empty()
ai_settings.increase_speed()
. . . .
. . . .# Увеличение уровня.
(1) . . . .stats.level += 1
(2) . . . .sb.prep_level()
. . . .
create_fleet(ai_settings, screen, ship, aliens)
Если все пришельцы уничтожены, программа увеличивает значение stats.level (1) и вызывает prep_level() для обновления уровня (2).
Чтобы убедиться в том, что изображения текущего счета и уровня правильно обновляются в начале новой игры, инициируйте сброс при нажатии кнопки Play:
game_functions.py
def check_play_button(ai_settings, screen, stats, sb, play_button, ship,
. . . .aliens, bullets, mouse_x, mouse_y):
"""Запускает новую игру при нажатии кнопки Play."""
button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
if button_clicked and not stats.game_active:
...
# Сброс игровой статистики.
stats.reset_stats()
stats.game_active = True
. . . .
. . . .# Сброс изображений счетов и уровня.
(1) . . . .sb.prep_score()
. . . .sb.prep_high_score()
. . . .sb.prep_level()
. . . .
# Очистка списков пришельцев и пуль.
aliens.empty()
bullets.empty()
. .
...
Определению check_play_button() необходим объект sb. Чтобы сбросить изображения на экране, после сброса игровых настроек следуют вызовы prep_score(), prep_high_score() и prep_level().
Затем объект sb передается check_events(), чтобы объект Scoreboard был доступен для check_play_button():
game_functions.py
def check_events(ai_settings, screen, stats, sb, play_button, ship, aliens,
. . . .bullets):
"""Обрабатывает нажатия клавиш и события мыши."""
for event in pygame.event.get():
if event.type == pygame.QUIT:
...
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_x, mouse_y = pygame.mouse.get_pos()
(1) . . . . . .check_play_button(ai_settings, screen, stats, sb, play_ button,
. . . . . . . .ship, aliens, bullets, mouse_x, mouse_y)
Определение check_events() должно получать sb в параметре, чтобы при вызове check_play_button() можно было передать sb в аргументе (1) .
Остается обновить вызов check_events() в alien_invasion.py, чтобы в нем также передавался объект sb:
alien_invasion.py
# Запуск основного цикла игры.
while True:
. .gf.check_events(ai_settings, screen, stats, sb, play_button, ship,
. . . .aliens, bullets)
...
Теперь количество пройденных уровней отображается на экране (рис. 14.5).
примечание
В некоторых классических играх выводимая информация снабжается текстовыми метками: «Уровень», «Рекорд» и т.д. Мы эти метки опустили, потому что смысл каждого числа понятен каждому, кто сыграл в Alien Invasion. Если вы включите эти метки, добавьте их в строки непосредственно перед вызовами font.render() в Scoreboard.
Рис. 14.5. Текущий уровень выводится под текущим счетом