ПРИМЕЧАНИЕ
В некоторых классических играх выводимая информация снабжается текстовыми метками: «Уро-
вень», «Рекорд» и т . д . Мы эти метки опустили, потому что смысл каждого числа понятен каждому,
кто сыграл в Alien Invasion . Если вы включите эти метки, добавьте их в строки непосредственно
перед вызовами font .render() в Scoreboard .
Подсчет очков 303
Рис. 14.5. Текущий уровень выводится под текущим счетом
Вывод количества кораблей
Остается вывести количество кораблей, оставшихся у игрока, но на этот раз инфор-
мация будет выводиться в графическом виде. Как во многих классических аркад-
ных играх, в левом верхнем углу экрана программа рисует несколько изображений
корабля. Каждый корабль обозначает одну оставшуюся попытку.
Для начала нужно сделать так, чтобы класс
Ship
наследовал от
Sprite
, — это не-
обходимо для создания группы кораблей:
ship.py
import pygame
from pygame.sprite import Sprite
class Ship(Sprite):
def __init__(self, ai_settings, screen):
"""Инициализирует корабль и задает его начальную позицию."""
super(Ship, self).__init__()
...
Здесь мы импортируем
Sprite
, объявляем о наследовании
Ship
от
Sprite
и вы-
зываем
super()
в начале
__init__()
.
Далее необходимо изменить
Scoreboard
и создать группу кораблей для вывода
на экран. Команды
import
и метод
__init__()
выглядят так:
scoreboard.py
import pygame.font
from pygame.sprite import Group
304 Глава 14 • Ведение счета
from ship import Ship
class Scoreboard():
"""Класс для вывода игровой информации."""
def __init__(self, ai_settings, screen, stats):
...
self.prep_level()
self.prep_ships()
...
Так как мы собираемся создать группу кораблей, программа импортирует классы
Group
и
Ship
. Метод
prep_ships()
будет вызываться после
prep_level()
. Он вы-
глядит так:
scoreboard.py
def prep_ships(self):
"""Сообщает количество оставшихся кораблей."""
self.ships = Group()
for ship_number in range(self.stats.ships_left):
ship = Ship(self.ai_settings, self.screen)
ship.rect.x = 10 + ship_number * ship.rect.width
ship.rect.y = 10
self.ships.add(ship)
Метод
prep_ships()
создает пустую группу
self.ships
для хранения экземпляров
кораблей . В ходе заполнения этой группы цикл выполняется по одному разу
для каждого корабля, оставшегося у игрока . В цикле создается новый корабль,
а координата x этого корабля задается так, чтобы корабли размещались рядом друг
с другом, разделенные интервалами величиной 10 пикселов . Координата y за-
дается так, чтобы корабли были смещены на 10 пикселов от верхнего края экрана
и были выровнены по изображению текущего счета . Наконец, каждый корабль
добавляется в группу
ships
.
Следующим шагом становится вывод кораблей на экран:
scoreboard.py
def show_score(self):
...
self.screen.blit(self.level_image, self.level_rect)
# Вывод кораблей.
self.ships.draw(self.screen)
При выводе кораблей на экран мы вызываем метод
draw()
для группы, а Pygame
рисует каждый отдельный корабль.
Чтобы игрок видел, сколько попыток у него в начале игры, мы вызываем
prep_
ships()
при запуске новой игры. Это происходит в функции
check_play_button()
из файла
game_functions .py
:
game_functions.py
def check_play_button(ai_settings, screen, stats, sb, play_button, ship,
Подсчет очков 305
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:
...
# Сброс изображений счетов и уровня.
sb.prep_score()
sb.prep_high_score()
sb.prep_level()
sb.prep_ships()
...
Метод
prep_ships()
также вызывается при столкновении пришельца с кораблем,
чтобы изображение обновлялось при потере корабля:
game_functions.py
def update_aliens(ai_settings, screen, stats, sb, ship, aliens, bullets):
...
# Проверка коллизий "пришелец-корабль".
if pygame.sprite.spritecollideany(ship, aliens):
ship_hit(ai_settings, screen, stats, sb, ship, aliens,
bullets)
# Проверяет, добрались ли пришельцы до нижнего края экрана.
check_aliens_bottom(ai_settings, screen, stats, sb, ship,
aliens, bullets)
def ship_hit(ai_settings, screen, stats, sb, ship, aliens,
bullets):
"""Обрабатывает столкновение корабля с пришельцем."""
if stats.ships_left > 0:
# Уменьшение ships_left.
stats.ships_left -= 1
# Обновление игровой информации.
sb.prep_ships()
# Очистка списков пришельцев и пуль.
...
Сначала параметр
sb
добавляется в определение
update_aliens()
. Затем про-
грамма передает
sb
функциям
ship_hit()
и
check_aliens_bottom()
, чтобы эти
функции имели доступ к объекту
Scoreboard
.
Затем определение
ship_hit()
изменяется с включением
sb
. Метод
prep_ships()
вызывается после уменьшения значения
ships_left
, так что при каждой потере
корабля выводится правильное количество изображений.
Вызов
ship_hit()
также включен в
check_aliens_bottom()
, так что эту функцию
тоже нужно обновить:
game_functions.py
def check_aliens_bottom(ai_settings, screen, stats, sb, ship, aliens,
bullets):
"""Проверяет, добрались ли пришельцы до нижнего края экрана."""
306 Глава 14 • Ведение счета
screen_rect = screen.get_rect()
for alien in aliens.sprites():
if alien.rect.bottom >= screen_rect.bottom:
# Происходит то же, что при столкновении с кораблем.
ship_hit(ai_settings, screen, stats, sb, ship, aliens, bullets)
break
Так как
check_aliens_bottom()
теперь получает параметр
sb
, мы добавляем аргу-
мент
sb
в вызов
ship_hit()
.
Остается добавить
sb
в вызов
update_aliens()
в файле
alien_invasion .py
:
alien_invasion.py
# Запуск основного цикла игры.
while True:
...
if stats.game_active:
ship.update()
gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens,
bullets)
gf.update_aliens(ai_settings, screen, stats, sb, ship, aliens,
bullets)
...
На рис. 14.6 показана полная игровая информация на экране, с количеством остав-
шихся кораблей в левой верхней части экрана.
Достарыңызбен бөлісу: |