В любой момент времени на экране может находиться не более трех пуль. Эта настройка будет использоваться в game_functions.py для проверки количества существующих пуль перед созданием новой пули в check_keydown_events():
game_functions.py
def check_keydown_events(event, ai_settings, screen, ship, bullets):
...
elif event.key == pygame.K_SPACE:
# Создание новой пули и включение ее в группу bullets.
. . . .if len(bullets) < ai_settings.bullets_allowed:
new_bullet = Bullet(ai_settings, screen, ship)
bullets.add(new_bullet)
При нажатии клавиши «пробел» программа проверяет длину bullets. Если значение len(bullets) меньше трех, создается новая пуля. Но, если на экране уже находятся три активные пули, при нажатии пробела ничего не происходит. Если вы запустите игру сейчас, вы сможете выпускать пули только группами по три.
Создание функции update_bullets()
Мы хотим, чтобы главный файл программы alien_invasion.py был как можно более простым, поэтому после написания и проверки кода управления пулями этот код можно переместить в модуль game_functions. Мы создадим новую функцию update_bullets() и добавим ее в конец game_functions.py:
game_functions.py
def update_bullets(bullets):
. ."""Обновляет позиции пуль и уничтожает старые пули."""
. .# Обновление позиций пуль.
bullets.update()
# Удаление пуль, вышедших за край экрана.
for bullet in bullets.copy():
if bullet.rect.bottom <= 0:
bullets.remove(bullet)
Код update_bullets() вырезается и вставляется из alien_invasion.py; единственным необходимым параметром функции является группа bullets.
Цикл while в alien_invasion.py снова выглядит просто:
alien_invasion.py
# Запуск основного цикла игры.
while True:
(1) gf.check_events(ai_settings, screen, ship, bullets)
(2)ship.update()
(3) . . . .gf.update_bullets(bullets)
(4)gf.update_screen(ai_settings, screen, ship, bullets)
В результате преобразования основной цикл содержит минимум кода, чтобы можно было легко прочитать имена функций и понять, что происходит в игре. Основной цикл проверяет ввод, полученный от игрока (1) , а затем обновляет позицию корабля (2) и всех выпущенных пуль (3). Затем обновленные позиции игровых элементов используются для вывода нового экрана в точке (4).
Создание функции fire_bullet()
Переместим код стрельбы в отдельную функцию, чтобы выстрел выполнялся всего одной строкой кода, а блок elif в check_keydown_events() оставался простым:
game_functions.py
def check_keydown_events(event, ai_settings, screen, ship, bullets):
"""Реагирует на нажатия клавиш."""
...
elif event.key == pygame.K_SPACE:
. . . .fire_bullet(ai_settings, screen, ship, bullets)
def fire_bullet(ai_settings, screen, ship, bullets):
. ."""Выпускает пулю, если максимум еще не достигнут."""
# Создание новой пули и включение ее в группу bullets.
if len(bullets) < ai_settings.bullets_allowed:
new_bullet = Bullet(ai_settings, screen, ship)
bullets.add(new_bullet)
Функция fire_bullet() просто содержит код, который использовался для выстрела при нажатии клавиши «пробел»; вызов fire_bullet() добавляется в check_keydown_events() при нажатии клавиши «пробел».
Запустите alien_invasion.py еще раз и убедитесь в том, что стрельба проходит без ошибок.
Упражнения
12-5. Боковая стрельба: напишите игру, в которой корабль размещается у левого края экрана, а игрок может перемещать корабль вверх и вниз. При нажатии клавиши «пробел» корабль стреляет, и пуля двигается вправо по экрану. Проследите за тем, чтобы пули удалялись при выходе за край экрана.
Итоги
В этой главе вы научились составлять план игры, а также усвоили базовую структуру игры, написанной с использованием Pygame. Вы узнали, как задать цвет фона и как сохранить настройки в отдельном классе, чтобы они были доступны для всех частей игры. Вы научились выводить изображения на экран и управлять перемещением игровых элементов. Также вы узнали, как создавать элементы, двигающиеся самостоятельно (например, пули, летящие по экрану), и как удалять объекты, которые стали лишними. Также в этой главе рассматривалась методика регулярного рефакторинга кода для упрощения текущей разработки.
В главе 13 в игру Alien Invasion будут добавлены пришельцы. К концу главы 13 игрок сможет сбивать корабли пришельцев — конечно, если они не доберутся до него первыми!
13. Осторожно, пришельцы!
В этой главе в игру Alien Invasion будут добавлены пришельцы. Сначала мы добавим одного пришельца у верхнего края экрана, а потом сгенерируем целый флот. Пришельцы будут перемещаться в сторону и вниз; при этом пришельцы, в которых попадают пули, исчезают с экрана. Наконец, мы ограничим количество кораблей у игрока, так что при гибели последнего корабля игра завершается.