Создание игр – перспективная и прибыльная сфера разработки приложений, в которой можно заработать много денег. Но это не так просто, поскольку необходимо разбираться в основах игровой механики, а также понимать, что надо для их создания с помощью Python. И с помощью библиотеки Pygame вы получите все необходимые для этого инструменты. Весь код, который будет приведен в этой статье, был написан в Python версии 3.7 и модификации Pygame 1.9.6.
Что такое Pygame?
Это библиотека, с помощью которой разработчики могут создавать игры. Она включает компоненты для программирования следующих элементов:
- Графики и анимации.
- Звука. Сюда же входит музыка, которая есть в играх.
- Управление. Сюда входит мышь, клавиатура, геймпад и так далее.
Этих компонентов достаточно для того, чтобы создать игру любой сложности. Конечно, надо понимать нюансы их использования, но все это приходит с опытом, по мере обучения и тренировки на реальных проектах.
Что такое игровой цикл и как его использовать?
Игровой цикл – это логика, заложенная в игру и какая работает постоянно. Каждый цикл в игре называется кадром. В каждом из них бывает огромное количество вещей, но все они могут быть разделены на три категории:
- Обработка ввода. Это все события, которые происходят вне игры. Таковыми могут быть клики мышью, нажатия каких-то клавиш на клавиатуре, и так далее.
- Обновление игры. Сюда входит изменение всего, что должно в рамках одного кадра. Например, если персонаж оказался в воздухе, он должен упасть вниз с помощью силы гравитации. Или же, если в игре два автомобиля на большой скорости встречаются, они должны взорваться.
- Рендеринг. На этом этапе осуществляется прорисовка всего того, что выводится на экран: фоны, персонажи, меню. Это приводит к тому, что на экране в нужном месте появляется то, что игрок должен видеть.
Параллельно со всеми этими компонентами, есть время. Этот аспект игрового цикла также очень важен. Многие игроки знают такой термин, как FPS. Означает он Frames Per Second. То есть, количество кадров в секунду. От FPS зависит то, какое количество раз цикл должен повторяться за секунду. Это позволяет не допустить того, чтобы игра была слишком медленной или быстрой.
Также нужно стараться поддерживать одинаковый FPS на разных компьютерах. Например, если персонажу для перемещения с левой части экрана к правой нужно 10 секунд, то такое же количество времени он должен потратить на всех компьютерах.
Что такое шаблон Pygame и как его создать?
Теперь, когда пользователь понимает, из чего состоит игра, теперь пора обучаться тому, как ее создавать. Для начала давайте попробуем создать самую простую программу Pygame, которая просто запускает игровой цикл. Именно с этого начинается любой проект, который создается в этой библиотеке.
Сначала надо импортировать требуемые компоненты и задать базовые переменные настроек игры.
# Pygame шаблон - скелет для нового проекта Pygame import pygame import random WIDTH = 360 # ширина игрового окна HEIGHT = 480 # высота игрового окна FPS = 30 # частота кадров в секунду Затем надо открыть окно игры. # создаем игру и окно pygame.init() pygame.mixer.init() # для звука screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("My Game") clock = pygame.time.Clock()
pygame.init() – это команда, запускающая библиотеку. screen – это окно приложения, в котором будет работать игровой цикл. И, наконец, для задания частоты кадров используется clock.
Давайте приступим к созданию игрового цикла, для начала.
# Цикл игры running = True while running: # Ввод процесса (события) # Обновление # Визуализация (сборка)
Игровой цикл – это цикл while, контроль которого лежит в области переменной running. Если необходимо закончить игру, достаточно лишь изменить значение этой переменной на False. Это приведет к окончанию цикла. Теперь можно заполнить каждый раздел базовым кодом.
Раздел рендеринга (отрисовки)
Начнем с рендеринга. Поскольку персонажи отсутствуют, вы можете заполнить экран сплошным цветом. Для этого вам нужно понимать, как ваш компьютер обрабатывает цвет.
Компьютерные экраны состоят из пикселей, каждый из которых содержит 3 элемента: красный, зеленый и синий. Цвет пикселя зависит от того, как горит каждый элемент:
Каждый из трех базовых цветов может иметь значения в диапазоне от 0 до 255. В первом случае он полностью отсутствует, а во втором он имеется в наличии. Таким образом, каждый элемент имеет 256 вариантов.
Чтобы узнать общее число цветов, которые могут быть показаны дисплеем компьютера, необходимо возвести это число в третью степень (поскольку всего базовых цветов).
Итого, получится 16 777 216 цветов.
Теперь, когда мы поняли принцип работы цветов, мы можем их задавать в начале приложения.
# Цвета (R, G, B) BLACK = (0, 0, 0) WHITE = (255, 255, 255) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) И, наконец, заполнить весь экран. # Рендеринг screen.fill(BLACK)
Но этого недостаточно. Экран компьютера так не работает. Изменение пикселя означает отправку команды видеокарте для передачи соответствующего изображения на экран. По компьютерным стандартам это очень медленный процесс. Если вам нужно много рисовать на экране, это займет много времени. Это можно исправить оригинальным способом, который называется двойной буферизацией.
Представьте, что у вас есть двусторонняя доска, которую можно повернуть, чтобы показать ту или иную сторону. Одна сторона будет отображать (то, что видит игрок), а другая останется скрытой, только компьютер сможет ее «увидеть». С каждым кадром рендеринг будет на обратной стороне платы. После завершения рендеринга доска поворачивается, и ее содержимое отображается игроку.
А это означает, что отрисовка осуществляется один раз за кадр, а не при добавлении каждого элемента. В Pygame этот процесс – автоматический. Достаточно лишь оповестить доску, чтобы она перевернулась после окончания отрисовки. Это реализуется с помощью команды flip().
# Рендеринг screen.fill(BLACK) # после отрисовки всего, переворачиваем экран pygame.display.flip()
Главная задача – сделать так, чтобы функция flip() располагалась в конце. Если попробовать нарисовать что-либо после поворота, эта картинка не будет показываться на экране.
Раздел ввода (событий)
Поскольку игра еще не создана, сказать о том, какие кнопки или элементы управления могут быть нужными, не получится. Но необходимо настроить одно важное событие. Если попробовать прямо сейчас запустить программу, то станет понятно, что нет возможности закрыть окно. Причем недостаточно просто нажать на крестик. Ведь необходимо сообщить программе, чтобы она тоже закрыла игру.
События происходят всегда. Например, если во время отрисовки игрок решит нажать на кнопку прыжка, как это обрабатывать? Если игнорировать это, то игрок будет разочарован.
Чтобы была возможность обрабатывать такие события, Pygame сохраняет все события, которые произошли с момента последнего кадра. Даже если игрок будет бить по кнопкам хаотично, ни одна из них не будет пропущена. В этом случае создается список, и с использованием цикла for можно пройтись по всем этим событиям.
for event in pygame.event.get(): # проверить закрытие окна if event.type == pygame.QUIT: running = False
В нашем случае было использовано событие pygame.QUIT. После того, как пользователь нажимает на кнопку завершения приложения, оно запускается. В нашем случае игровой цикл завершается. Но можно задать другие действия, например, вопрос о том, сохранять ли игровой прогресс.
Контроль частоты кадров в секунду
В нашем случае пока нет информации, которая могла бы быть помещена в раздел Update. Тем не менее, настройка FPS должна контролировать скорость игры, и нам нужно быть уверенным в том, что это происходит. Это делается таким образом.
while running: # держим цикл на правильной скорости clock.tick(FPS)
С помощью команды tick() Pygame позволяет определить продолжительность цикла, а потом сделать паузу, чтобы кадр длился столько времени, сколько нужно. Если задать значение FPS 30, то тогда длина кадра будет 1/30. То есть, он будет длиться 0,03 секунды. Если цикл кода (обновление, рендеринг и прочее) занимает 0,01 секунды, то тогда будет пауза на 0,02 секунды.
Выводы
После всего этого, необходимо убедиться в том, что окно игры закрывается после завершения игрового цикла. Для этого используется функция pygame.quit() в конце кода. Финальный шаблон Pygame тогда будет выглядеть следующим образом.
# Pygame шаблон - скелет для нового проекта Pygame import pygame import random WIDTH = 360 HEIGHT = 480 FPS = 30 # Задаем цвета WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) # Создаем игру и окно pygame.init() pygame.mixer.init() screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("My Game") clock = pygame.time.Clock() # Цикл игры running = True while running: # Держим цикл на правильной скорости clock.tick(FPS) # Ввод процесса (события) for event in pygame.event.get(): # check for closing window if event.type == pygame.QUIT: running = False # Обновление # Рендеринг screen.fill(BLACK) # После отрисовки всего, переворачиваем экран pygame.display.flip() pygame.quit()
Все, теперь есть окончательный шаблон Pygame. Далее его осталось сохранить в файле с понятным названием. Например, pygame_template.py, чтобы в дальнейшем его можно было использовать для создания новых проектов pygame.
Далее мы продолжим использовать этот шаблон для изучения процесса отрисовки объектов на экране и их движения.