Когда пришелец сталкивается с кораблем, программа уменьшает количество оставшихся кораблей на 1, уничтожает всех существующих пришельцев и пули, создает новый флот и возвращает корабль в середину экрана. (Также игра ненадолго приостанавливается, чтобы игрок заметил столкновение и перестроился перед появлением нового флота.)
Бульшая часть этого кода будет включена в функцию ship_hit():
game_functions.py
import sys
(1) from time import sleep
import pygame
...
def ship_hit(ai_settings, stats, screen, ship, aliens, bullets):
. ."""Обрабатывает столкновение корабля с пришельцем."""
. .# Уменьшение ships_left.
(2) . .stats.ships_left -= 1
. .
. .# Очистка списков пришельцев и пуль.
(3) . .aliens.empty()
. .bullets.empty()
. .
. .# Создание нового флота и размещение корабля в центре.
(4) . .create_fleet(ai_settings, screen, ship, aliens)
. .ship.center_ship()
. .
. .# Пауза.
(5) . .sleep(0.5)
? def update_aliens(ai_settings, stats, screen, ship, aliens, bullets):
...
# Проверка коллизий "пришелец-корабль".
if pygame.sprite.spritecollideany(ship, aliens):
. . . .ship_hit(ai_settings, stats, screen, ship, aliens, bullets)
Сначала мы импортируем функцию sleep() из модуля time, чтобы приостановить игру (1) . Новая функция ship_hit() управляет реакцией игры на столкновение корабля с пришельцем. Внутри ship_hit() число оставшихся кораблей уменьшается на 1 (2), после чего происходит очистка групп aliens и bullets (3).
Затем программа создает новый флот и выравнивает корабль по центру нижнего края (4). (Вскоре мы добавим метод center_ship() в класс Ship.) Наконец, после внесения изменений во все игровые элементы, но до перерисовки изменений на экране делается короткая пауза, чтобы игрок увидел, что его корабль столкнулся с пришельцем (5). После завершения паузы sleep() код переходит к функции update_screen(), которая перерисовывает новый флот на экране.
Также необходимо обновить определение update_aliens() и добавить параметры stats, screen и bullets ?, чтобы эти значения можно было передать при вызове ship_hit().
Ниже приведен новый метод center_ship(); добавьте его в конец ship.py:
ship.py
def center_ship(self):
. ."""Размещает корабль в центре нижней стороны."""
. .self.center = self.screen_rect.centerx
Чтобы выровнять корабль по центру, мы задаем атрибуту center корабля значение, соответствующее центру экрана (полученное при помощи атрибута screen_rect).
примечание
Обратите внимание: программа никогда не создает более одного корабля. Один экземпляр ship используется на протяжении всей игры, а при столкновении с пришельцем он просто возвращается к центру экрана. О том, что у игрока не осталось ни одного корабля, программа узнаёт из атрибута ships_left.
Запустите игру, подстрелите нескольких пришельцев, а затем позвольте пришельцу столкнуться с кораблем. Происходит небольшая пауза, на экране появляется новый флот вторжения, а корабль возвращается в центр нижней части экрана.
Достижение нижнего края экрана
Если пришелец добирается до нижнего края экрана, программа будет реагировать так же, как при столкновении с кораблем. Добавьте для проверки этого условия новую функцию, которая будет называться update_aliens():
game_functions.py
def check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets):
. ."""Проверяет, добрались ли пришельцы до нижнего края экрана."""
. .screen_rect = screen.get_rect()
. .for alien in aliens.sprites():
(1) . . . .if alien.rect.bottom >= screen_rect.bottom:
. . . . . .# Происходит то же, что при столкновении с кораблем.
. . . . . .ship_hit(ai_settings, stats, screen, ship, aliens, bullets)
. . . . . .break
. . . . . .
def update_aliens(ai_settings, stats, screen, ship, aliens, bullets):
...
. .# Проверка пришельцев, добравшихся до нижнего края экрана.
(2) . .check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets)
Функция check_aliens_bottom() проверяет, есть ли хотя бы один пришелец, добравшийся до нижнего края экрана. Условие выполняется, когда атрибут rect.bottom пришельца больше или равен атрибуту rect.bottom экрана (1) . Если пришелец добрался до низа, вызывается функция ship_hit(). Если хотя бы один пришелец добрался до нижнего края, проверять остальных уже не нужно, поэтому после вызова ship_hit() цикл прерывается.
Функция check_aliens_bottom() вызывается после обновления позиций всех пришельцев и после проверки столкновений «пришелец-корабль» (2). Теперь новый флот будет появляться как при столкновении корабля с пришельцем, так и в том случае, если кто-то из пришельцев смог добраться до нижнего края экрана.
Конец игры
Программа Alien Invasion уже на что-то похожа, но игра длится бесконечно. Значение ships_left просто продолжает уходить в отрицательную бесконечность. Добавим в GameStats новый атрибут — флаг game_active, который завершает игру после потери последнего корабля:
game_stats.py
def __init__(self, settings):
....
. .# Игра Alien Invasion запускается в активном состоянии.
. .self.game_active = True