Флаг button_clicked содержит значение True или False (1) ; а игра перезапускается только в том случае, если пользователь нажал кнопку Play, а игра не активна в данный момент (2). Чтобы протестировать это поведение, запустите новую игру и многократно щелкайте в том месте, где должна находиться кнопка Play. Если все работает так, как положено, нажатия кнопки Play не должны влиять на ход игры.
Сокрытие указателя мыши
Указатель мыши должен быть видимым, чтобы пользователь мог начать игру, но после начала игры он только мешает. Чтобы исправить этот недостаток, мы скроем указатель мыши после того, как игра станет активной:
game_functions.py
def check_play_button(ai_settings, screen, stats, 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:
. . . .# Указатель мыши скрывается.
. . . .pygame.mouse.set_visible(False)
...
Вызов set_visible() со значением False приказывает Pygame скрыть указатель, когда он находится над окном игры.
После завершения игры указатель должен появляться снова, чтобы игрок мог нажать кнопку Play для запуска новой игры. Эту задачу решает следующий код:
game_functions.py
def ship_hit(ai_settings, screen, stats, ship, aliens, bullets):
"""Обрабатывает столкновение корабля с пришельцем."""
if stats.ships_left > 0:
...
else:
stats.game_active = False
. . . .pygame.mouse.set_visible(True)
Указатель снова становится видимым сразу же после того, как игра становится неактивной, что происходит в ship_hit(). Внимание к подобным деталям сделает вашу игру более профессиональной, а игрок сможет сосредоточиться на игре вместо того, чтобы разбираться в сложностях пользовательского интерфейса.
Упражнения
14-1. Запуск игры клавишей P: так как в Alien Invasion игрок управляет кораблем с клавиатуры, для запуска игры также лучше использовать клавиатуру. Добавьте код, с которым игрок сможет запустить игру нажатием клавиши P. Возможно, часть кода из check_play_button() стоит переместить в функцию start_game(), которая будет вызываться из check_play_button() и check_keydown_events().
14-2. Учебная стрельба: создайте у правого края экрана прямоугольник, который двигается вверх и вниз с постоянной скоростью. У левого края располагается корабль, который перемещается вверх и вниз игроком и стреляет по движущейся прямоугольной мишени. Добавьте кнопку Play для запуска игры. После трех промахов игра заканчивается, а на экране снова появляется кнопка Play. Нажатие этой кнопки перезапускает игру.
Повышение сложности
В текущей версии после того, как весь флот пришельцев будет уничтожен, игрок переходит на новый уровень, но сложность игры остается неизменной. Давайте немного оживим игру и повысим ее сложность; для этого скорость игры будет повышаться каждый раз, когда игрок уничтожает весь флот.
Изменение настроек скорости
Начнем с реорганизации класса Settings и разделения настроек игры на две категории: постоянные и изменяющиеся. Также необходимо проследить за тем, чтобы настройки, изменяющиеся в ходе игры, сбрасывались в исходное состояние в начале новой игры. Метод __init__() из файла settings.py выглядит так:
settings.py
def __init__(self):
. ."""Инициализирует статические настройки игры."""
# Настройки экрана
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (230, 230, 230)
# Настройки корабля
self.ship_limit = 3
. . . .
# Настройки пуль
self.bullet_width = 3
self.bullet_height = 15
self.bullet_color = 60, 60, 60
self.bullets_allowed = 3
# Настройки пришельцев
self.fleet_drop_speed = 10
. . . .
. .# Темп ускорения игры
(1) . .self.speedup_scale = 1.1
(2) . .self.initialize_dynamic_settings()
Значения, которые остаются неизменными, по-прежнему инициализируются в методе __init__(). В точке (1) добавляется настройка speedup_scale, управляющая быстротой нарастания скорости; со значением 2 скорость удваивается каждый раз, когда игрок переходит на следующий уровень, а со значением 1 скорость остается постоянной. С таким значением, как 1,1, скорость будет увеличиваться в достаточной степени, чтобы игра усложнилась, но не стала невозможной. Наконец, вызов initialize_dynamic_settings() инициализирует значения атрибутов, которые должны изменяться в ходе игры (2).
Код initialize_dynamic_settings() выглядит так:
settings.py
def initialize_dynamic_settings(self):
. ."""Инициализирует настройки, изменяющиеся в ходе игры."""
. .self.ship_speed_factor = 1.5
. .self.bullet_speed_factor = 3
. .self.alien_speed_factor = 1
. .# fleet_direction = 1 обозначает движение вправо; а -1 - влево.
. .self.fleet_direction = 1
Метод задает исходные значения скоростей корабля, пуль и пришельцев. Эти скорости будут увеличиваться по ходу игры и будут сбрасываться каждый раз, когда игрок запускает новую игру. Мы включаем в этот метод fleet_direction, чтобы пришельцы в начале новой игры всегда двигались вправо.