Книга «Изучаем Python»


    Глава 12  •  Стреляющий корабль Рис. 12.3



Pdf көрінісі
бет132/238
Дата07.01.2022
өлшемі7,86 Mb.
#18670
түріКнига
1   ...   128   129   130   131   132   133   134   135   ...   238
Байланысты:
2 5343781172763690906

252    Глава 12  •  Стреляющий корабль

Рис. 12.3. Экран игры после серии выстрелов

Группа 


bullets

 передается 

check_keydown_events()

 . Когда игрок нажимает про-

бел, создается новая пуля (экземпляр 

Bullet


 с именем 

new_bullet

), которая добав-

ляется в группу 

bullets

  методом 

add()

; код 


bullets.add(new_bullet)

 сохраняет 

новую пулю в группе 

bullets


.

Группу 


bullets

 необходимо добавить в число параметров в определении 

check_events()

 , а также передать в аргументе при вызове 

check_keydown_

events()


.

Параметр 

bullets

 передается функции 

update_screen()

 , которая рисует пули 

на экране. Метод 

bullets.sprites()

 возвращает список всех спрайтов в группе 

bullets


. Чтобы нарисовать все выпущенные пули на экране, программа перебирает 

спрайты в 

bullets

 и вызывает для каждого 

draw_bullet()

 .


Если запустить 

alien_invasion .py

 сейчас, вы сможете двигать корабль влево и вправо 

и выпускать сколько угодно пуль. Пули перемещаются вверх по экрану и исчезают 

при достижении верхнего края (рис. 12.3). Размер, цвет и скорость пуль можно из-

менить при помощи настроек в 

settings .py

.

Удаление старых пуль



На данный момент пули исчезают по достижении верхнего края, но только потому, 

что Pygame не может нарисовать их выше края экрана. На самом деле пули про-

должают существовать; их координата y продолжает уменьшаться. И это создает 

проблему, потому что пули продолжают потреблять память и вычислительные 

мощности.



Стрельба    253

От старых пуль необходимо избавиться, иначе игра замедлится из-за большого 

объема лишней работы. Для этого необходимо определить момент, когда атрибут 

bottom


 прямоугольника пули достигнет 0, — это означает, что пуля вышла за верх-

ний край экрана:



alien_invasion.py

# Запуск основного цикла игры.

while True:

gf.check_events(ai_settings, screen, ship, bullets)

ship.update()

bullets.update()

    

        # Удаление пуль, вышедших за край экрана.



          for bullet in bullets.copy():

            if bullet.rect.bottom <= 0:



                 bullets.remove(bullet)

        print(len(bullets))



gf.update_screen(ai_settings, screen, ship, bullets)

Удалять элементы из списка или группы в цикле 

for

 не следует, поэтому переби-



рать нужно копию группы. Метод 

copy()


 используется для создания цикла 

for


 , 

в котором возможно изменять содержимое 

bullets

. Программа проверяет каждую 

пулю и определяет, вышла ли она за верхний край экрана . Если пуля пересекла 

границу, она удаляется из 

bullets

 . В точке  добавляется команда 

print

, которая 



сообщает, сколько пуль сейчас существует в игре; по выведенному значению можно 

убедиться в том, что пули действительно были удалены.

Если код работает правильно, вы можете понаблюдать за выводом на терминале 

и убедиться в том, что количество пуль уменьшается до 0 после того, как очередной 

залп уходит за верхний край экрана. После того как вы запустите игру и убедитесь 

в том, что пули правильно удаляются из группы, удалите команду 

print

. Если ко-



манда останется в программе, она существенно замедлит игру, потому что вывод 

на терминал занимает больше времени, чем отображение графики в игровом окне.

Ограничение количества пуль

Многие игры-«стрелялки» ограничивают количество пуль, одновременно находя-

щихся на экране, чтобы у игроков появился стимул стрелять более метко. То же 

самое будет сделано и в игре Alien Invasion.

Сначала сохраним максимально допустимое количество пуль в 

settings .py

:

settings.py

# Параметры пули

self.bullet_width = 3

self.bullet_height = 15

self.bullet_color = 60, 60, 60

  self.bullets_allowed = 3

В любой момент времени на экране может находиться не более трех пуль. Эта на-

стройка будет использоваться в 

game_functions .py

 для проверки количества суще-

ствующих пуль перед созданием новой пули в 

check_keydown_events()

:



254    Глава 12  •  Стреляющий корабль

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:

gf.check_events(ai_settings, screen, ship, bullets)



ship.update()

        gf.update_bullets(bullets)



gf.update_screen(ai_settings, screen, ship, bullets)

В результате преобразования основной цикл содержит минимум кода, чтобы 

можно было легко прочитать имена функций и понять, что происходит в игре. 

Основной цикл проверяет ввод, полученный от игрока , а затем обновляет пози-

цию  корабля  и всех выпущенных пуль . Затем обновленные позиции игровых 

элементов используются для вывода нового экрана в точке .



Итоги    255

Создание функции 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

 еще раз и убедитесь в том, что стрельба проходит без 

ошибок.



Достарыңызбен бөлісу:
1   ...   128   129   130   131   132   133   134   135   ...   238




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет