Python. Добавление кнопки Play.
В текущей версии игра начинается сразу же после запуска alien_invasion.py. После очередных изменений игра будет запускаться в неактивном состоянии и предлагать игроку нажать кнопку Play для запуска. Для этого включите следующий код в game_stats.py:
Программа запускается в неактивном состоянии, а игру можно запустить только нажатием кнопки Play.
Python. Создание класса Button.
Так как в Pygame не существует встроенного метода создания кнопок, мы напишем класс Button для создания заполненного прямоугольника с текстовой надписью. Следующий код может использоваться для создания кнопок в любой игре. Ниже приведена первая часть класса Button; сохраните ее в файле button.py:
Сначала программа импортирует модуль pygame.font, который позволяет Pygame выводить текст на экран. Метод __init__() получает параметры self, объекты ai_settings и screen, а также строку msg с текстом кнопки. Размеры кнопки задаются , после чего атрибуты button_color и text_color задаются так, чтобы прямоугольник кнопки был окрашен в ярко-зеленый цвет, а текст выводился белым цветом. Происходит подготовка атрибута font для вывода текста. Аргумент None сообщает Pygame, что для вывода текста должен использоваться шрифт по умолчанию, а значение 48 определяет размер текста. Чтобы выровнять кнопку по центру экрана, мы создаем объект rect для кнопки и задаем его атрибут center в соответствии с одноименным атрибутом экрана. Pygame выводит строку текста в виде графического изображения. Эта задача решается методом prep_msg(). Код prep_msg() выглядит так:
Метод prep_msg() должен получать параметр self и текст, который нужно вывести в графическом виде (msg). Вызов font.render() преобразует текст, хранящийся в msg, в изображение, которое затем сохраняется в msg_image . Методу font.render() также передается логический признак режима сглаживания текста. В остальных аргументах передаются цвет шрифта и цвет фона. В нашем примере режим сглаживания включен (True), а цвет фона совпадает с цветом фона кнопки. (Если цвет фона не указан, Pygame пытается вывести шрифт с прозрачным фоном.) Изображение текста выравнивается по центру кнопки, для чего создается объект rect изображения, а его атрибут center приводится в соответствие с одноименным атрибутом кнопки. Остается создать метод draw_button(), который может вызываться для отображения кнопки на экране:
Вызов метода screen.fill() рисует прямоугольную часть кнопки. Затем вызов screen.blit() выводит изображение текста на экран с передачей изображения и объекта rect, связанного с изображением. Класс Button готов.
Python. Вывод кнопки на экран.
В программе класс Button используется для создания кнопки Play. Так как нам нужна только одна кнопка Play, мы создадим кнопку прямо в файле alien_invasion.py:
Программа импортирует класс Button и создает экземпляр play_button , после чего передает play_button функции update_screen(), чтобы кнопка появлялась при обновлении экрана. Затем следует внести изменения в update_screen() в game_functions.py , чтобы кнопка Play появлялась только в неактивном состоянии игры:
Чтобы кнопка Play не закрывалась другими элементами экрана, мы отображаем ее после всех остальных игровых элементов, но перед переключением на новый экран. Теперь при запуске Alien Invasion в центре экрана отображается кнопка Play.
Python. Запуск игры.
Чтобы при нажатии кнопки Play запускалась новая игра, добавьте в файл game_functions.py следующий код для отслеживания событий мыши над кнопкой:
Обновленное определение check_events() получает параметры stats и play_button. Параметр stats будет использоваться для обращения к флагу game_active, а play_button — для проверки того, была ли нажата кнопка Play. Pygame обнаруживает событие MOUSEBUTTONDOWN, когда игрок щелкает в любой точке экрана, но мы хотим ограничить игру, чтобы она реагировала только на щелчки на кнопке Play. Для этого будет использоваться метод pygame.mouse.get_pos(), возвращающий кортеж с координатами x и y точки щелчка. Эти значения передаются функции check_play_button() , которая использует метод collidepoint() для проверки того, находится ли точка щелчка в пределах области, определяемой прямоугольником кнопки Play. Если точка находится в пределах кнопки, флаг game_active переводится в состояние True, и игра начинается! При вызове check_events() в alien_invasion.py должны передаваться два дополнительных аргумента, stats и play_button:
К этому моменту вы сможете запустить и сыграть полноценную игру. После завершения игры значение game_active становится равным False, а кнопка Play снова появится на экране.
Python. Сброс игры.
Пока игра при первом нажатии кнопки Play, но не работает после завершения первой игры, потому что условия, приводящие к окончанию игры, еще не были сброшены. Чтобы игра сбрасывалась при каждом нажатии кнопки Play, необходимо сбросить игровую статистику, стереть старых пришельцев и пули, построить новый флот и вернуть корабль в центр нижней стороны, в game_functions.py:
Обновляем определение check_play_button(), чтобы в нем были доступны объекты ai_settings, stats, ship, aliens и bullets. Эти объекты необходимы для сброса настроек, изменившихся в ходе игры, и для обновления визуальных элементов игры. Обновляется игровая статистика, вследствие чего игрок получает три новых корабля. После этого флаг game_active переводится в состояние True (чтобы игра началась сразу же после выполнения кода функции), группы aliens и bullets очищаются , создается новый флот, а корабль выравнивается по центру. Для этого необходимо изменить определение check_events(), как и вызов check_ play_button() в game_functions.py:
Определению check_events() необходим параметр aliens, который будет передаваться check_play_button(). Также обновляется вызов heck_play_button() с включением соответствующих аргументов. Теперь обновите вызов check_events() в alien_invasion.py, чтобы в нем передавался аргумент aliens:
Сейчас игра будет правильно переходить в исходное состояние при каждом нажатии Play.
Python. Блокировка кнопки Play.
У кнопки Play в нашем приложении есть одна проблема: область кнопки на экране продолжает реагировать на щелчки, даже если кнопка Play не отображается. Если случайно щелкнуть на месте кнопки Play после начала игры, то игра перезапустится! Чтобы исправить этот недостаток, следует запускать игру только в том случае, если флаг game_active находится в состоянии False. Меняем в game_functions.py:
Флаг button_clicked содержит значение True или False ; а игра перезапускается только в том случае, если пользователь нажал кнопку Play, а игра не активна в данный момент. Чтобы протестировать это поведение, запустите новую игру и многократно щелкайте в том месте, где должна находиться кнопка Play. Если все работает так, как положено, нажатия кнопки Play не должны влиять на ход игры.
Python. Сокрытие указателя мыши.
Указатель мыши должен быть видимым, чтобы пользователь мог начать игру, но после начала игры он только мешает. Чтобы исправить этот недостаток, мы скроем указатель мыши после того, как игра станет активной (в game_functions.py):
Вызов set_visible() со значением False приказывает Pygame скрыть указатель, когда он находится над окном игры. После завершения игры указатель должен появляться снова, чтобы игрок мог нажать кнопку Play для запуска новой игры. Эту задачу решает следующий код в game_functions.py:
Указатель снова становится видимым сразу же после того, как игра становится неактивной, что происходит в ship_hit(). Внимание к подобным деталям сделает вашу игру более профессиональной, а игрок сможет сосредоточиться на игре вместо того, чтобы разбираться в сложностях пользовательского интерфейса.