Изучаем PyGame на простых примерах
16 июля 2025
PyGame — это библиотека для создания мультимедийных приложений на Python. Зачастую позиционируется, как простой движок для создания двухмерных игр. Скажем, вы хотите написать свой сокобан или пошаговую стратегию в стиле Героев III, но не хотите учить Unity или Unreal Engine. Тогда PyGame создан для вас. Впрочем, как мы скоро убедимся, PyGame пригоден не только для игр.
В качестве примера рассмотрим демку, рисующую синусоиду:
import pygame
from math import sin, pi
width, height = 1024, 768
blue = (0, 0, 100)
white = (255, 255, 255)
amplitude = height // 2 - 50
freq = 4
phase = 0
show_fps = True
pygame.init()
font = pygame.font.Font(None, 36)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Sine Wave Demo")
running = True
clock = pygame.time.Clock()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
running = False
elif event.key == pygame.K_f:
show_fps = not show_fps
screen.fill(blue)
points = []
for x in range(width):
s = sin(2 * pi * freq * x / width + phase)
y = height // 2 + amplitude * s
points.append((x, y))
pygame.draw.lines(screen, white, False, points, 2)
if show_fps:
fps = clock.get_fps()
fps_text = font.render(f"FPS: {fps:.1f}", True, white)
screen.blit(fps_text, (15, 15))
pygame.display.flip()
phase += 0.1
clock.tick(60)
pygame.quit()
Так выглядит результат:
Здесь фаза синусоиды является функцией от времени, что создает иллюзию плавного движения графика справа налево. В левом верхнем углу выводится частота кадров в секунду.
Вот как это работает:
pygame.init()
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Sine Wave Demo")
Здесь происходит инициализация библиотеки. Затем создается окно указанной ширины и высоты в пикселях. Окну присваивается заголовок. Переменная screen
является экземпляром класса Surface. Это один из ключевых классов в PyGame, представляющий собой двухмерное изображение. Например, двумерный «холст», с которым мы работаем, а также спрайты — все это экземпляры Surface.
while running:
# ...
fps = clock.get_fps()
# ...
clock.tick(60)
Класс Clock, как следует из названия, представляет собой внутриигровые часы. Метод tick
должен вызываться после отрисовки каждого кадра. Он вычисляет время, прошедшее с последнего вызова, и из него определяет частоту кадров в секунду (FPS). С помощью опционального аргумента можно сообщить целевую частоту кадров. Тогда tick
будет создавать задержку, чтобы FPS не превышал желаемый. Метод get_fps
возвращает реально вычисленный FPS.
if event.type == pygame.QUIT:
# ...
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
# ...
elif event.key == pygame.K_f:
# ...
Вызов pygame.event.get()
возвращает список новых событий, таких, как нажатия клавиш и закрытие окна программы. Итерируемся по списку, обрабатываем.
white = (255, 255, 255)
# ...
screen.fill(blue)
points = []
for x in range(width):
s = sin(2 * pi * freq * x / width + phase)
y = height // 2 + amplitude * s
points.append((x, y))
pygame.draw.lines(screen, white, False, points, 2)
Сначала заполняем холст синим цветом. Далее создаем список координат точек, принадлежащих синусоиде. С помощью pygame.draw.lines
соединяем эти точки белыми линиями толщиной в два пикселя. Помимо линий pygame.draw умеет рисовать прямоугольники, эллипсы, и так далее.
# ...
fps_text = font.render(f"FPS: {fps:.1f}", True, white)
screen.blit(fps_text, (15, 15))
Здесь мы создаем дэфолтный шрифт высотой 36 пикселей. Далее при помощи метода render
создается новый Surface, на котором выведен текущий FPS. Затем с помощью метода Surface.blit
выводим его на холсте в левом верхнем углу. Название blit
является акронимом к bit block transfer. Термин blitting является устоявшимся в мире компьютерной графики.
Обновляем изображение на дисплее / холсте.
Деинициализация модуля, метод обратный к init
. Вызывать его не обязательно. Все ресурсы в любом случае будут освобождены при завершении скрипта.
Примечание: На момент написания этих строк в PyGame имеется баг, из-за которого pygame.quit
иногда повисает на Linux. Есть несколько воркэраундов, наиболее универсальный из которых — завершать скрипт через os._exit(0)
.
Пусть пример получился и не самым захватывающим, зато он демонстрирует ~85% всех возможностей PyGame. Это действительно очень простая библиотека. По крайней мере, в плане ее интерфейса. Если хотите более интересный пример, могу предложить классическую демку, рисующую «плазму»:
Код этой демки доступен здесь. Плазма красиво переливается разными цветами, однако показать это в блоге у меня, увы, не получится. Вам придется установить PyGame и запустить скрипт, чтобы увидеть результат в динамике. Качественно код плазмы не намного сложнее кода синусоиды. Заинтересованным читателям предлагается изучить скрипт самостоятельно. Реализована возможность запуска в полноэкранном режиме. А значит, перед нами полноценный скринсейвер.
Плазма примечательна тем, что рисуется попиксельно. При жалении, на PyGame можно написать не слишком динамичную игру, стилизованную под pixel art. При этом, из методов PyGame понадобится лишь Surface.set_at
.
Резюмируя, я вижу следующие применения PyGame:
- Написание 2D игр. Притом, библиотека с одинаковым успехом подойдет как для змейки, так и для какой-нибудь сложной пошаговой стратегии. А может быть, и не только пошаговой;
- Написание демок. Неплохая подборка примеров доступна здесь. В этих примерах использованы JavaScript и Canvas, но суть та же;
- Используя
Surface.set_at
, можно получить опыт, схожий с опытом программирования под ретро-компьютеры, в смысле прямой работы с «видео памятью». Только без ассемблера и без ретро-железа; - Эмуляция каких-нибудь ZX Spectrum, БК-0010-01 и Искры 1080 Тарту;
- Реализация алгоритма Брезенхэма для прямых линий и окружностей. Данный алгоритм вполне себе актуален на тех же микроконтроллерах;
- Рисование каких-нибудь кривых Гильберта и Серпинского. Их часто используют для объяснения рекурсии начинающим программистам;
- Можно законтрибьютить в сам PyGame, если вам нравиться работать над игровыми движками или чем-то, что их напоминает;
К сожалению, в рамках одного поста не получилось рассмотреть абсолютно все возможности PyGame. Например, за кадром остались работа со звуком и мышью. Справка по всем доступным классам и их методам, а также большое количество примеров, доступны на официальном сайте PyGame. Также есть неплохая книга «Beginning Python Games Development With PyGame, Second Edition», авторы Harrison Kinsley и Will McGugan.
Метки: Python.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.