def create_fleet(ai_settings, screen, aliens):
. ."""Создает флот пришельцев."""
. .# Создание пришельца и вычисление количества пришельцев в ряду.
. .# Интервал между соседними пришельцами равен одной ширине пришельца.
(1) . .alien = Alien(ai_settings, screen)
(2) . .alien_width = alien.rect.width
(3) . .available_space_x = ai_settings.screen_width - 2 * alien_width
(4) . .number_aliens_x = int(available_space_x / (2 * alien_width))
. .
. .# Создание первого ряда пришельцев.
(5) . .for alien_number in range(number_aliens_x):
. . . .# Создание пришельца и размещение его в ряду.
? . . . .alien = Alien(ai_settings, screen)
. . . .alien.x = alien_width + 2 * alien_width * alien_number
. . . .alien.rect.x = alien.x
. . . .aliens.add(alien)
Бульшая часть этого кода уже была описана ранее. Для размещения пришельцев необходимо знать ширину и высоту одного пришельца, и мы создаем его в точке (1) перед выполнением вычислений. Этот пришелец не войдет во флот, поэтому он не включается в группу aliens. В точке (2) ширина пришельца определяется по его атрибуту rect, а полученное значение сохраняется в alien_width, чтобы избежать лишних обращений к атрибуту rect. В точке (3) вычисляется горизонтальное пространство и количество пришельцев, которые в нем поместятся.
По сравнению с исходными формулами всего одно изменение: мы используем int(), чтобы вычисленное количество пришельцев (4) было целым, — во-первых, неясно, что делать с неполным пришельцем, а во-вторых, функция range() должна получать целое число. Функция int() отсекает дробную часть числа, фактически выполняя округление в меньшую сторону. (И это правильно: лучше оставить лишнее свободное место в каждом ряду, чем забивать ряды до отказа.)
Затем создается цикл от 0 до количества создаваемых пришельцев (5). В теле цикла создается новый пришелец, после чего задается его координата x для размещения его в ряду ?. Каждый пришелец сдвигается вправо на одну ширину от левого поля. Затем ширина пришельца умножается на 2, чтобы учесть полное пространство, выделенное для одного пришельца, включая пустой интервал справа, а полученная величина умножается на позицию пришельца в ряду. Затем новый пришелец добавляется в группу aliens.
Рис. 13.3. Первый ряд пришельцев
Запустив программу Alien Invasion, вы увидите, что на экране появился первый ряд пришельцев (рис. 13.3).
Первый ряд сдвинут влево, и это хорошо, потому что флот пришельцев должен двигаться вправо, пока не дойдет до края экрана, затем немного опуститься вниз, затем двигаться влево и т.д. Как и в классической игре Space Invaders, такое перемещение интереснее, чем постепенное снижение по прямой. Движение будет продолжаться до тех пор, пока все пришельцы не будут сбиты или пока пришелец не столкнется с кораблем или нижним краем экрана.
примечание
В зависимости от выбранной ширины экрана расположение первого ряда пришельцев в вашей системе может выглядеть немного иначе.
Если бы создание флота на этом было завершено, то функцию create_fleet(), пожалуй, можно было бы оставить в таком виде, но работа еще не закончена, поэтому мы немного подчистим код функции. Ниже приведена версия create_fleet() с двумя новыми функциями: get_number_aliens_x() и create_alien():
game_functions.py
(1) def get_number_aliens_x(ai_settings, alien_width):
. ."""Вычисляет количество пришельцев в ряду."""
available_space_x = ai_settings.screen_width - 2 * alien_width
number_aliens_x = int(available_space_x / (2 * alien_width))
. .return number_aliens_x
def create_alien(ai_settings, screen, aliens, alien_number):
. ."""Создает пришельца и размещает его в ряду."""
alien = Alien(ai_settings, screen)
(2) . .alien_width = alien.rect.width
alien.x = alien_width + 2 * alien_width * alien_number
alien.rect.x = alien.x
aliens.add(alien)
. .
def create_fleet(ai_settings, screen, aliens):
"""Создает флот пришельцев."""
# Создание пришельца и вычисление количества пришельцев в ряду.
alien = Alien(ai_settings, screen)
(3) . .number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width)
. .
# Создание первого ряда пришельцев.
for alien_number in range(number_aliens_x):
(4) . . . .create_alien(ai_settings, screen, aliens, alien_number)
Код get_number_aliens_x() нисколько не изменился по сравнению с create_fleet() (1) . Код create_alien() почти не изменился, разве что для определения ширины используется только что созданный пришелец (2). В точке (3) код вычисления горизонтальных интервалов заменяется вызовом get_number_aliens_x(), а строка с alien_width удалена, потому что теперь задача решается в create_alien(). В точке (4) вызывается функция create_alien(). Рефакторинг упрощает добавление новых строк и создание всего флота.