Создать игру на языке python
Пишем игру на Python
Прежде чем мы начнём программировать что-то полезное на Python, давайте закодим что-нибудь интересное. Например, свою игру, где нужно не дать шарику упасть, типа Арканоида. Вы, скорее всего, играли в детстве во что-то подобное, поэтому освоиться будет просто.
Логика игры
Есть игровое поле — простой прямоугольник с твёрдыми границами. Когда шарик касается стенки или потолка, он отскакивает в другую сторону. Если он упадёт на пол — вы проиграли. Чтобы этого не случилось, внизу вдоль пола летает платформа, а вы ей управляете с помощью стрелок. Ваша задача — подставлять платформу под шарик как можно дольше. За каждое удачное спасение шарика вы получаете одно очко.
Алгоритм
Чтобы реализовать такую логику игры, нужно предусмотреть такие сценарии поведения:
Хитрость в том, что всё это происходит параллельно и независимо друг от друга. То есть пока шарик летает, мы вполне можем двигать платформу, а можем и оставить её на месте. И когда шарик отскакивает от стен, это тоже не мешает другим объектам двигаться и взаимодействовать между собой.
Получается, что нам нужно определить три класса — платформу, сам шарик и счёт, и определить, как они реагируют на действия друг друга. Поле нам самим определять не нужно — для этого есть уже готовая библиотека. А потом в этих классах мы пропишем методы — они как раз и будут отвечать за поведение наших объектов.
По коням, пишем на Python
Для этого проекта вам потребуется установить и запустить среду Python. Как это сделать — читайте в нашей статье.
Начало программы
Чтобы у нас появилась графика в игре, используем библиотеку Tkinter. Она входит в набор стандартных библиотек Python и позволяет рисовать простейшие объекты — линии, прямоугольники, круги и красить их в разные цвета. Такой простой Paint, только для Python.
Чтобы создать окно, где будет видна графика, используют класс Tk(). Он просто делает окно, но без содержимого. Чтобы появилось содержимое, создают холст — видимую часть окна. Именно на нём мы будем рисовать нашу игру. За холст отвечает класс Canvas(), поэтому нам нужно будет создать свой объект из этого класса и дальше уже работать с этим объектом.
Если мы принудительно не ограничим скорость платформы, то она будет перемещаться мгновенно, ведь компьютер считает очень быстро и моментально передвинет её к другому краю. Поэтому мы будем искусственно ограничивать время движения, а для этого нам понадобится модуль Time — он тоже стандартный.
Последнее, что нам глобально нужно, — задавать случайным образом начальное положение шарика и платформы, чтобы было интереснее играть. За это отвечает модуль Random — он помогает генерировать случайные числа и перемешивать данные.
Запишем всё это в виде кода на Python:
Мы подключили все нужные библиотеки, сделали и настроили игровое поле. Теперь займёмся классами.
Шарик
Сначала проговорим словами, что нам нужно от шарика. Он должен уметь:
Платформа
Сделаем то же самое для платформы — сначала опишем её поведение словами, а потом переведём в код. Итак, вот что должна уметь платформа:
А вот как это будет в виде кода:
Можно было не выделять счёт в отдельный класс и каждый раз обрабатывать вручную. Но здесь реально проще сделать класс, задать нужные методы, чтобы они сами потом разобрались, что и когда делать.
От счёта нам нужно только одно (кроме конструктора) — чтобы он правильно реагировал на касание платформы, увеличивал число очков и выводил их на экран:
У нас всё готово для того, чтобы написать саму игру. Мы уже провели необходимую подготовку всех элементов, и нам остаётся только создать конкретные объекты шарика, платформы и счёта и сказать им, в каком порядке мы будем что делать.
Смысл игры в том, чтобы не уронить шарик. Пока этого не произошло — всё движется, но как только шарик упал — нужно показать сообщение о конце игры и остановить программу.
Посмотрите, как лаконично выглядит код непосредственно самой игры:
Библиотека Pygame / Часть 1. Введение
Это первая часть серии руководств «Разработка игр с помощью Pygame». Она предназначена для программистов начального и среднего уровней, которые заинтересованы в создании игр и улучшении собственных навыков кодирования на Python.
Код в уроках был написан на Python 3.7 и Pygame 1.9.6
Что такое Pygame?
Pygame — это «игровая библиотека», набор инструментов, помогающих программистам создавать игры. К ним относятся:
Игровой цикл
В сердце каждой игры лежит цикл, который принято называть «игровым циклом». Он запускается снова и снова, делая все, чтобы работала игра. Каждый цикл в игре называется кадром.
В каждом кадре происходит масса вещей, но их можно разбить на три категории:
Речь идет обо всем, что происходит вне игры — тех событиях, на которые она должна реагировать. Это могут быть нажатия клавиш на клавиатуре, клики мышью и так далее.
Изменение всего, что должно измениться в течение одного кадра. Если персонаж в воздухе, гравитация должна потянуть его вниз. Если два объекта встречаются на большой скорости, они должны взорваться.
В этом шаге все выводится на экран: фоны, персонажи, меню. Все, что игрок должен видеть, появляется на экране в нужном месте.
Время
Еще один важный аспект игрового цикла — скорость его работы. Многие наверняка знакомы с термином FPS, который расшифровывается как Frames Per Second (или кадры в секунду). Он указывает на то, сколько раз цикл должен повториться за одну секунду. Это важно, чтобы игра не была слишком медленной или быстрой. Важно и то, чтобы игра не работала с разной скоростью на разных ПК. Если персонажу необходимо 10 секунд на то, чтобы пересечь экран, эти 10 секунд должны быть неизменными для всех компьютеров.
Создание шаблона Pygame
Теперь, зная из каких элементов состоит игра, можно переходить к процессу написания кода. Начать стоит с создания простейшей программы pygame, которая всего лишь открывает окно и запускает игровой цикл. Это отправная точка для любого проекта pygame.
В начале программы нужно импортировать необходимые библиотеки и задать базовые переменные настроек игры:
Дальше необходимо открыть окно игры:
Теперь необходимо создать игровой цикл:
Раздел рендеринга (отрисовки)
Начнем с раздела отрисовки. Персонажей пока нет, поэтому экран можно заполнить сплошным цветом. Чтобы сделать это, нужно разобраться, как компьютер обрабатывает цвета.
Экраны компьютеров сделаны из пикселей, каждый из которых содержит 3 элемента: красный, зеленый и синий. Цвет пикселя определяется тем, как горит каждый из элементов:
Каждый из трех основных цветов может иметь значение от 0 (выключен) до 255 (включен на 100%), так что для каждого элемента есть 256 вариантов.
Узнать общее количество отображаемых компьютером цветов можно, умножив:
Теперь, зная, как работают цвета, можно задать их в начале программ:
А после этого — заполнить весь экран.
Но этого недостаточно. Дисплей компьютера работает не так. Изменить пиксель — значит передать команду видеокарте, чтобы она передала соответствующую команду экрану. По компьютерным меркам это очень медленный процесс. Если нужно нарисовать на экране много всего, это займет много времени. Исправить это можно оригинальным способом, который называется — двойная буферизация. Звучит необычно, но вот что это такое.
Представьте, что у вас есть двусторонняя доска, которую можно поворачивать, показывая то одну, то вторую сторону. Одна будет дисплеем (то, что видит игрок), а вторая — оставаться скрытой, ее сможет «видеть» только компьютер. С каждым кадром рендеринг будет происходить на задней части доски. Когда отрисовка завершается, доска поворачивается и ее содержимое демонстрируется игроку.
А это значит, что процесс отрисовки происходит один раз за кадр, а не при добавлении каждого элемента.
В pygame это происходит автоматически. Нужно всего лишь сказать доске, чтобы она перевернулась, когда отрисовка завершена. Эта команда называется flip() :
Главное — сделать так, чтобы функция flip() была в конце. Если попытаться отрисовать что-то после поворота, это содержимое не отобразится на экране.
Раздел ввода (событий)
Игры еще нет, поэтому пока сложно сказать, какие кнопки или другие элементы управления понадобятся. Но нужно настроить одно важное событие. Если попытаться запустить программу сейчас, то станет понятно, что нет возможности закрыть окно. Нажать на крестик в верхнем углу недостаточно. Это тоже событие, и необходимо сообщить программе, чтобы она считала его и, соответственно, закрыла игру.
События происходят постоянно. Что, если игрок нажимает кнопку прыжка во время отрисовки? Это нельзя игнорировать, иначе игрок будет разочарован. Для этого pygame сохраняет все события, произошедшие с момента последнего кадра. Даже если игрок будет лупить по кнопкам, вы не пропустите ни одну из них. Создается список, и с помощью цикла for можно пройтись по всем из них.
Контроль FPS
Пока что нечего поместить в раздел Update (обновление), но нужно убедиться, что настройка FPS контролирует скорость игры. Это можно сделать следующим образом:
Команда tick() просит pygame определить, сколько занимает цикл, а затем сделать паузу, чтобы цикл (целый кадр) длился нужно время. Если задать значение FPS 30, это значит, что длина одного кадра — 1/30, то есть 0,03 секунды. Если цикл кода (обновление, рендеринг и прочее) занимает 0,01 секунды, тогда pygame сделает паузу на 0,02 секунды.
Наконец, нужно убедиться, что когда игровой цикл завершается, окно игры закрывается. Для этого нужно поместить функцию pygame.quit() в конце кода. Финальный шаблон pygame будет выглядеть вот так:
В следующем руководстве этот шаблон будет использован как отправная точка для изучения процесса отрисовки объектов на экране и их движения.
Появились вопросы? Задайте на Яндекс Кью
У блога есть сообщество на Кью >> Python Q 7 900 5 825 ₽/мес.
PyGame: учебник по программированию игр на Python
Когда я начал изучать компьютерное программирование в конце прошлого тысячелетия, это было связано с моим желанием писать компьютерные игры. Я пытался понять, как писать игры на каждом языке и на каждой изученной платформе, включая Python.
К концу этой статьи вы сможете:
Вы можете получить весь код из этой статьи по этой ссылке:
Фон и настройка
Чтобы установить pygame на свою платформу, используйте соответствующую pip команду:
Вы можете проверить установку, загрузив один из примеров, поставляемых с библиотекой:
Если появится игровое окно, значит, pygame установлен правильно! Если вы столкнетесь с проблемами, то в руководстве Getting Started изложены некоторые известные проблемы и предупреждения для всех платформ.
Основная программа PyGame
Прежде чем приступить к конкретике, давайте рассмотрим основную pygame программу. Эта программа создает окно, заполняет фон белым и рисует синий круг в середине:
Когда вы запустите эту программу, вы увидите окно, которое выглядит так:
Давайте разберем этот код, раздел за разделом:
Это версия pygame «Привет, мир». Теперь давайте углубимся в концепции этого кода.
PyGame Concepts
Так как pygame и библиотека SDL являются переносимыми на разные платформы и устройства, им необходимо определять и работать с абстракциями для различных аппаратных реалий. Понимание этих концепций и абстракций поможет вам спроектировать и разработать свои собственные игры.
Инициализация и Модули
Дисплеи и поверхности
Изображения и Rects
Ладно, хватит теории. Давайте разработаем и напишем игру!
Базовый дизайн игры
Перед тем, как вы начнете писать какой-либо код, всегда полезно иметь какой-то дизайн. Так как это обучающая игра, давайте разработаем для нее базовый геймплей:
Когда он описывал программные проекты, мой бывший коллега говорил: «Вы не знаете, что делаете, пока не узнаете, что не делаете». Имея это в виду, вот некоторые вещи, которые не будут рассмотрены в этом руководстве:
Вы можете попробовать свои силы в добавлении этих и других функций в свою программу.
Импорт и инициализация PyGame
После импорта pygame вам также нужно будет его инициализировать. Это позволяет pygame подключать его абстракции к вашему конкретному оборудованию:
Настройка дисплея
Теперь вам нужно что-то нарисовать! Создайте экран, который будет общим холстом:
Вы создаете экран для использования, Вы создаете экран для использования, вызывая pygame.display.set_mode() и передавая кортеж или список с желаемой шириной и высотой. В этом случае размер окна 800×600, как определено константами SCREEN_WIDTH и SCREEN_HEIGHT в строках 20 и 21. Это возвращает Surface, которая представляет внутренние размеры окна. Это часть окна, которой вы можете управлять, в то время как ОС контролирует границы окна и строку заголовка.
Если вы запустите эту программу сейчас, вы увидите, что окно ненадолго всплывет, а затем сразу исчезнет при выходе из программы. В следующем разделе вы сосредоточитесь на основном игровом цикле, чтобы гарантировать, что ваша программа завершает работу только при правильном вводе.
Настройка игрового цикла
Каждая игра от понга до форнита использует игровой цикл для управления игровым процессом. Игровой цикл выполняет четыре очень важных вещи:
Каждый цикл игрового цикла называется фреймом, и чем быстрее вы сможете делать вещи в каждом цикле, тем быстрее будет работать ваша игра. Кадры продолжают появляться до тех пор, пока не будет выполнено какое-либо условие для выхода из игры. В вашем дизайне есть два условия, которые могут завершить игровой цикл:
Обработка событий
Давайте внимательнее посмотрим на этот игровой цикл:
Когда вы добавите эти строки в предыдущий код и запустите его, вы увидите окно с пустым или черным экраном:
Окно не исчезнет, пока вы не нажмете клавишу Esc или не запустите QUIT событие, закрыв окно.
Рисование на экране
В примере программы вы рисовали на экране с помощью двух команд:
Координаты (SCREEN_WIDTH/2, SCREEN_HEIGHT/2) говорят вашей программе размещать surf точно в центре экрана, но это не совсем так:
Спрайты
Игроки
Вот как вы используете Sprite объекты в текущей игре для определения игрока. Вставьте этот код после строки 18:
Запустите этот код. Вы увидите белый прямоугольник примерно в середине экрана:
Пользовательский ввод
Итак, вы узнали, как настраивать pygame и рисовать объекты на экране. Теперь начинаетыся самое интересное! Вы сделаете игрока управляемым с помощью клавиатуры.
Поместите это в свой игровой цикл сразу после цикла обработки событий. Это возвращает словарь, содержащий клавиши, нажимаемые в начале каждого кадра:
Теперь вы можете перемещать прямоугольник игрока по экрану с помощью клавиш со стрелками:
Вы можете заметить две небольшие проблемы:
Чтобы игрок оставался на экране, вам нужно добавить некоторую логику, чтобы определять, собирается ли rect уйти с экрана. Для этого вы проверяете, не вышли ли координаты rect за пределы экрана. Если это так, то вы даете команду программе переместить его обратно на край
Теперь давайте добавим несколько врагов!
Враги
Что за игра без врагов? Вы будете использовать методы, которые вы уже изучили, чтобы создать базовый класс врагов, а затем создадите множество из них, чтобы ваш игрок избегал их. Сначала импортируйте random библиотеку:
Есть четыре заметных различия между Enemy и Player :
Группы спрайтов
Давайте посмотрим, как создавать группы спрайтов. Вы создадите два разных Group объекта:
Вот как это выглядит в коде:
Есть только одна проблема … У тебя нет врагов! Вы можете создать кучу врагов в начале игры, но игра быстро станет скучной, когда все они покинут экран через несколько секунд. Вместо этого давайте рассмотрим, как поддерживать постоянный приток врагов в ходе игры.
Пользовательские события
Дизайн призывает врагов появляться через равные промежутки времени. Это означает, что через заданные интервалы вам нужно сделать две вещи:
У вас уже есть код, который обрабатывает случайные события. Цикл событий предназначен для поиска случайных событий, происходящих в каждом кадре, и обработки их соответствующим образом. К счастью, pygame не ограничивает вас использованием только тех типов событий, которые он определил. Вы можете определить свои собственные события для обработки по своему усмотрению.
Давайте посмотрим, как создать пользовательское событие, которое генерируется каждые несколько секунд. Вы можете создать собственное событие, назвав его:
Добавьте код для обработки вашего нового события:
Обнаружение столкновения
Ваш игровой дизайн призывает к завершению игры, когда враг сталкивается с игроком. Проверка на столкновения – это базовая техника программирования игр, которая обычно требует некоторой нетривиальной математики, чтобы определить, будут ли два спрайта перекрывать друг друга.
Вот где такие рамки pygame пригодятся! Написание кода обнаружения столкновений является утомительным, но в pygame есть много способов обнаружения столкновений доступных для использования.
Вот как это выглядит в коде:
На данный момент у вас есть основные элементы игры на месте:
Теперь давайте немного нарядим его, сделаем его более играбельным и добавим некоторые расширенные возможности, которые помогут ему выделиться.
Изображения спрайтов
Хорошо, у вас есть игра, но давайте будем честными … Это некрасиво. Игрок и враги – просто белые блоки на черном фоне. Это было по последнему слову техники, когда Pong был новичком, но теперь он уже не работает. Давайте заменим все эти скучные белые прямоугольники более крутыми изображениями, которые сделают игру похожей на настоящую.
Ранее вы узнали, что изображения на диске могут быть загружены в Surface с некоторой помощью модуля изображений. Для этого урока мы сделали небольшой самолет для игрока и несколько ракет для врагов. Вы можете использовать это искусство, нарисовать свое собственное или загрузить бесплатные игровые графические ресурсы для использования. Вы можете щелкнуть ссылку ниже, чтобы загрузить изображения, использованные в этом руководстве:
Изменение конструкторов объектов
Прежде чем использовать изображения для представления спрайтов игрока и врага, необходимо внести некоторые изменения в их конструкторы. Приведенный ниже код заменяет использованный ранее код:
Вот как выглядят аналогичные изменения для Enemy :
Запуск программы сейчас должен показать, что это та же игра, что и у вас раньше, за исключением того, что теперь вы добавили несколько красивых графических скинов с изображениями. Но зачем останавливаться на том, чтобы просто сделать красивую внешность игрока и врага? Давайте добавим несколько проносящихся облаков, чтобы создать впечатление летящего по небу самолета.
Добавление фоновых изображений
Для фоновых облаков вы используете те же принципы, что и для Player и Enemy :
Вот как выглядит Cloud :
Чтобы облака появлялись через определенные промежутки времени, вы будете использовать код создания события, аналогичный тому, который вы использовали для создания новых врагов. Поместите это прямо под событием создания врага:
Затем создайте новый Group для хранения каждого вновь созданного cloud :
Затем добавьте обработчик для нового ADDCLOUD события в обработчик событий:
Наконец, убедитесь, что clouds обновляются каждый кадр:
Вы создаете несколько групп, так что вы можете изменить способ перемещения или поведения спрайтов, не влияя на движение или поведение других спрайтов.
Скорость игры
Во время тестирования игры вы могли заметить, что враги двигаются немного быстро. Если нет, то это нормально, поскольку разные машины будут видеть разные результаты на этом этапе.
Причина этого в том, что игровой цикл обрабатывает кадры настолько быстро, Количество кадров, обрабатываемых каждую секунду, называется частотой кадров, и правильное определение этого значения – разница между играбельной игрой и той, которую можно забыть.
Использование Clock для установки воспроизводимой частоты кадров требует всего двух строк кода. Первый создает новые часы перед началом игрового цикла:
Передача меньшей частоты кадров приведет к большему количеству времени в каждом кадре для вычислений, в то время как более высокая частота кадров обеспечивает более плавный (и, возможно, более быстрый) игровой процесс:
Поиграйте с этим номером, чтобы увидеть, что вам больше нравится!
Звуковые эффекты
Пока что вы сосредоточились на игровом процессе и визуальных аспектах игры. А теперь давайте посмотрим, как придать вашей игре звуковой привкус. pygame предоставляет mixer для обработки всех действий, связанных со звуком. Вы будете использовать классы и методы этого модуля для создания фоновой музыки и звуковых эффектов для различных действий.
Название mixer относится к тому факту, что модуль смешивает различные звуки в единое целое. Используя music субмодуль, вы Название mixer относится к тому факту, что модуль смешивает различные звуки в единое целое. Используя подмодуль музыки, вы можете передавать отдельные звуковые файлы в различных форматах, таких как MP3, Ogg и Mod. Вы также можете использовать «Звук» для удержания одного звукового эффекта для воспроизведения в форматах Ogg или несжатом WAV. Все воспроизведение происходит в фоновом режиме, поэтому, когда вы воспроизводите звук, метод немедленно возвращается по мере воспроизведения звука.
Примечание. В pygame документации заявляется, что поддержка MP3 ограничена, а неподдерживаемые форматы могут вызвать сбои системы. Звуки, упомянутые в этой статье, были протестированы, и мы рекомендуем тщательно протестировать любые звуки перед выпуском игры.
После инициализации системы вы можете настроить свои звуки и фоновую музыку:
Строки с 143 по 145 загружают три звука, которые вы будете использовать для различных звуковых эффектов. Первые два – это звуки подъема и падения, которые воспроизводятся, когда игрок движется вверх или вниз. Последний – звук, используемый при столкновении. Вы также можете добавить другие звуки, например звук, когда создается Враг, или последний звук, когда игра заканчивается.
Для столкновения между игроком и врагом вы воспроизводите звук, когда обнаруживаются столкновения:
Здесь вы сначала останавливаете любые другие звуковые эффекты, потому что при столкновении игрок больше не движется. Затем вы проигрываете звук столкновения и продолжаете исполнение оттуда.
Наконец, когда игра окончена, все звуки должны прекратиться. Это верно независимо от того, заканчивается ли игра из-за столкновения или пользователь выходит вручную. Для этого добавьте следующие строки в конце программы после цикла:
Технически эти последние несколько строк не требуются, так как программа заканчивается сразу после этого. Однако если позже вы решите добавить в игру вводный экран или экран выхода, то после завершения игры может появиться больше кода.
Проверьте это снова, и вы должны увидеть что-то вроде этого:
Примечание к источникам
Возможно, вы заметили комментарий в строках 136-137 при загрузке фоновой музыки, в котором указан источник музыки и ссылка на лицензию Creative Commons. Это было сделано, потому что создатель этого звука требовал этого. В лицензионных требованиях указывалось, что для использования звука необходимо предоставить как надлежащую атрибуцию, так и ссылку на лицензию.
Вот некоторые источники музыки, звука и искусства, которые вы можете найти для полезного контента:
Поскольку вы создаете свои игры и используете загруженный контент, такой как произведения искусства, музыка или код из других источников, убедитесь, что вы соблюдаете условия лицензирования этих источников.
Вывод
Из этого урока вы узнали, как программирование игр pygame отличается от стандартного процедурного программирования. Вы также узнали:
Вы можете найти весь код, графику и звуковые файлы для этой статьи, щелкнув ссылку ниже: