Зомби против Танков: Простая игра на Python и Pygame Zero

Игра на Python

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

С исходным кодом вы можете ознакомиться по ссылке.

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Содержание статьи

На этот раз наша игра на Python будет немного (только немного!) сложнее:

Простая игра на Python и Pygame Zero

Новые аспекты, с которыми мы познакомимся в данном руководстве:

  • Танк будет менять свое направление при нажатии стрелок на клавиатуре;
  • Танк будет стрелять. Внедрить эту возможность может оказаться намного сложнее, чем вы могли предположить;
  • Каждый выстрел будет сопровождаться звуком;
  • Зомби будут обладать некоторым «искусственным интеллектом», то есть они будут пытаться двигаться в сторону игрока;
  • Счет будет отображаться на экране. Также в игре будет отдельный экран, который будет выводиться после завершения игры.

Приступим! Поскольку данная статья основана на предыдущей записи (игра Арканоид), я не буду объяснять код, который я объяснил в той записи. Например, как работают клавиши со стрелками.

Скелет основного кода игры

Это базовый код, который просто откроет экран и отобразит фоновое изображение.

Создание игры на Python

Давайте отобразим танк:

И добавим код для реагирования по нажатиям клавиш клавиатуры:

Проверим, что получилось:

Создание игры на Python

Танк всегда смотрит передней частью вниз, независимо от того, в какую сторону мы движемся. Давайте это исправим.

В верхней части кода добавьте эти углы разворота:

Поскольку танк уже смотрит вниз, угол для движения вниз равен 0.

Аналогично, чтобы переместить танк дулом вверх, нам нужно повернуть изображение на 180 градусов.

Эти значения будут зависеть от вашего исходного изображения, поэтому вам придется поиграть с ними.

Давайте обновим код, чтобы он применял эти углы:

Таким образом, помимо перемещения танка, мы изменяем угол его наклона в зависимости от того, какую клавишу мы нажали. Посмотрим, что получается:

Создание игры на Python

Отлично!

Механика выстрела из танка

Заставить танк стрелять оказалось не так просто. Главная причина в том, что нам нужно, чтобы пуля продолжала лететь в фоновом режиме, пока танки (а позже и зомби) двигаются.

Это означает, что мы должны обрабатывать состояние пули в фоновом режиме. К счастью, для этого есть отличный способ. Но прежде давайте определим графику для пули:

У нас есть переменная под названием bullet_fired. Позже я расскажу, зачем она нам нужна.

Мы будем стрелять пулей при нажатии пробела. Код для этого следующий:

Это может показаться сложным, поэтому я расскажу обо всем по частям.

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

Создание игры на Python

Если я не пропишу эту строку: bullet.x = blue_tank.x-30, пуля появится в середине танка. В нашем случае создается впечатление, что танк выпустил пулю. Давайте снова посмотрим на код:

Все, что мы делаем, это проверяем направление движения танка и рисуем пулю перед ним. Это не обязательно, просто выглядит красиво :)

Мы также будем воспроизводить звук выстрела, когда пуля выпущена.

Атрибут laserretro_004 — это название нашего звукового файла в папке sounds.

Протестируйте его:

Создание игры на Python

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

Выстрел в фоновом режиме

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

В Pygame Zero есть функция, позволяющая планировать выполнение задач в фоновом режиме.

Метод clock.schedule() планирует выполнение задачи в фоновом режиме. Первое значение — это функция (которую мы напишем). Второе — время в секундах когда она должна быть выполнена повторно.

Таким образом, каждые 5 секунд Pygame Zero будет вызывать нашу функцию shoot_bullet. Давайте напишем эту функцию.

Сперва проверим переменную bullet_fired. Мы хотим запускать эту функцию только в том случае, если пользователь нажал пробел, то есть выстрелил пулей. Поскольку функция работает в фоновом режиме, она ничего не будет делать, пока не будет нажата клавиша.

И после этого, в зависимости от того, в какую сторону направлен танк, мы будем менять местоположение пули. Например:

Поэтому, если танк обращен влево, мы будем изменять ось x пули на -10 при каждом вызове функции. Это создаст впечатление, что пуля летит.

Также нам нужно проверить, не улетела ли пуля за пределы экрана:

Если пуля выходит за пределы экрана, мы устанавливаем значение переменной bullet_fired на False. Это означает, что функция не будет запущена, пока пользователь снова не нажмет пробел.

Давайте проверим, как это работает.

Создание игры на Python

Превосходно.

Добавление зомби в игре

Немного базовых настроек:

Мы создаем список для хранения зомби и устанавливаем их скорость. Также создадим переменную для хранения счета игры.

Затем добавим это в функцию draw()

Мы запланировали функцию для создания зомби каждые 5 секунд, другую — для их перемещения, и, наконец — для отображения счета. Давайте рассмотрим все по очереди.

Создание зомби в игре

Сначала мы проверим длину списка zombie_list, поскольку нам нужно только 10 зомби за раз. Вы можете изменить это число — от него будет зависеть сложность игры.

Затем нам нужно выбрать случайное число от 0 до 3.

  • Если случайное число равно 0, зомби генерируется в верхней части экрана;
  • Если 1, то зомби появляется в правой части экрана;
  • Если 2 и 3 — внизу и слева.

Это обеспечит случайное появление зомби по всему экрану, а не только в одной точке. Весь код выглядит следующим образом:

Я создаю случайных зомби в одном из четырех углов экрана. Давайте рассмотрим следующую часть кода:

Мы говорим: Выберите положение y зомби случайным образом в точке от 40 пикселей до (HEIGHT-40) пикселей. Точка x просто устанавливается равной 1 — она тоже может быть случайной.

Затем мы добавляем только что созданного зомби в наш список.

То же самое мы делаем для всех остальных направлений.

Перемещение зомби

Сначала разберем наш «искусственный интеллект». Он довольно глупый, но ведь и зомби не отличаются особым умом :D

Зомби будут пытаться двигаться в сторону танка. Поскольку мы знаем его местоположение, мы изменим положение зомби таким образом, чтобы они пытались следовать за танком.

Обратите внимание на эту часть кода:

Так что если значение x зомби находится слева от танка, мы переместим его вправо (увеличив его x). И наоборот.

То же самое для движения вверх/вниз — мы проверяем y танка и обновляем это значение для зомби.

Далее нам нужно проверить, получил ли зомби удар от танка:

Мы перебираем зомби с помощью цикла и рисуем их:

Если зомби сталкивается с пулей, мы удаляем зомби из списка и увеличиваем счет на +1.

Однако, если зомби столкнется с танком, игра закончится.

Давайте реализуем экран для завершения игры:

Создание экрана «Игра окончена»

Обновим функцию draw(), чтобы она вызывала метод draw только в том случае, если игра не закончилась:

Нам также нужно указать условие для завершения игры:

Если игра закончилась, экран окрашивается синим цветом и выводится надпись Game Over.

Давайте протестируем код:

Создание игры на Python

Вот и все!

Как можно улучшить игру?

Если вы хотите бросить себе вызов, то можете попробовать улучшить игру. Помните, что код доступен по ссылке: https://github.com/shantnu/zombie_tanks.

  • В игре есть баг — попробуйте выстрелить. Пуля движется вместе с танком! Попробуйте исправить это;
  • Добавьте начальный экран, на котором будет отображаться уровень сложности — вы можете увеличить количество и скорость зомби;
  • Чтобы сделать ИИ более забавным, добавьте несколько зомби, которые двигаются случайным образом, а не всегда следуют за игроком.
  • Добавьте возможность перезапуска игры.

Статья о создании новой игры появится уже через несколько недель! Готовьтесь!