Первое окно в PyGame: init, display.set_mode и игровой цикл

Разбираем код, с которого начинается любая игра на PyGame: pygame.init(), display.set_mode() и игровой цикл с обработкой событий. Готовый шаблон проверен на PyGame 2.6.1: скопируйте, запустите и получите первое окно 800 × 600 с заголовком и заливкой цветом. Плюс пять частых ошибок новичков и способы их исправить.
Статью написал:
Ваня Буявец, продюсер, основатель Checkroi
Ваня Буявец
Основатель Checkroi, продюсер, эксперт в выборе онлайн-курсов
Все 2345 статей автора Подписаться на Телеграм-канал
Одобрено экспертом:
Наташа Буявец, основатель Checkroi, эксперт по онлайн-курсам
Наташа Буявец
Основательница Checkroi, продюсер Youtube-каналов, эксперт по онлайн-курсам
Все 3006 экспертных мнений Подписаться на Телеграм-канал
Обложка: Первое окно в PyGame: init, display.set_mode и игровой цикл

Окно в PyGame создаётся тремя вызовами: pygame.init() включает библиотеку, pygame.display.set_mode((800, 600)) открывает окно размером 800 × 600 пикселей, а pygame.display.set_caption() задаёт текст в заголовке. Чтобы окно не схлопнулось сразу после запуска, нужен игровой цикл: while, который обрабатывает события и перерисовывает кадр. Ниже вы найдёте минимальный рабочий код, проверенный на PyGame 2.6.1, и разбор каждой строки. Если вы пока выбираете, на чём делать первую игру, загляните в наш гайд по разработке игр для новичков: PyGame там разобран в сравнении с другими движками.

CheckroiCheckroiПодборка курсов по Python570 курсов • 46 школСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить

Установка PyGame: одна команда

PyGame ставится через pip, как любая библиотека Python. Откройте терминал и выполните:

pip install pygame

Если на компьютере несколько версий Python, надёжнее вызывать pip через конкретный интерпретатор: python -m pip install pygame. Тогда библиотека точно попадёт туда, откуда вы запускаете скрипты.

Проверить установку можно прямо из консоли Python:

>>> import pygame
pygame 2.6.1 (SDL 2.32.70, Python 3.14.3)
Hello from the pygame community. https://www.pygame.org/contribute.html
>>> pygame.ver
'2.6.1'

Приветствие «Hello from the pygame community» при первом импорте печатает сама библиотека, это норма. Если видите эти строки, PyGame установлен и готов к работе. Если же pip падает с ошибкой, загляните в отдельную инструкцию, как установить PyGame: там разобраны типовые проблемы с версиями Python.

Готовый код первого окна в PyGame

Скопируйте код в файл main.py и запустите: откроется тёмное окно с заголовком «Моя первая игра», которое закрывается крестиком. Это скелет, с которого начинается практически любой проект на PyGame.

import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Моя первая игра")

clock = pygame.time.Clock()
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    screen.fill((30, 30, 40))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Что здесь происходит по шагам:

  1. import pygame подключает библиотеку. Если строка падает с ошибкой, вернитесь к разделу про установку.
  2. pygame.init() инициализирует все модули библиотеки: дисплей, звук, шрифты.
  3. pygame.display.set_mode((800, 600)) создаёт окно и возвращает поверхность screen, на которой мы будем рисовать.
  4. pygame.display.set_caption("Моя первая игра") подписывает окно.
  5. Цикл while running каждый кадр читает события, заливает фон цветом, показывает картинку и ограничивает частоту 60 кадрами в секунду.
  6. pygame.quit() корректно выгружает библиотеку после выхода из цикла.
Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединиться

Что делает каждая функция

pygame.init()

Функция запускает все подсистемы PyGame разом и возвращает кортеж из двух чисел: сколько модулей инициализировалось успешно и сколько с ошибкой. Проверять результат в учебных проектах необязательно: если дисплей поднялся, остальное почти всегда в порядке.

Вызывать pygame.init() нужно один раз в начале программы, до работы с экраном, звуком и шрифтами. Повторные вызовы безопасны, уже включённые модули они не трогают. Существует и точечный вариант pygame.display.init(), который поднимает только дисплей, но на старте проще включить всё сразу общим pygame.init().

pygame.display.set_mode()

Главный аргумент функции — кортеж (ширина, высота) в пикселях: сначала width, затем height. Возвращает она объект Surface, экранную поверхность. Всё, что вы нарисуете на ней, попадёт на монитор после вызова pygame.display.flip(). Переменную с этой поверхностью традиционно называют screen: это соглашение вы встретите почти в каждом туториале.

Вторым аргументом можно передать флаги режима окна:

Флаг Что делает
pygame.FULLSCREEN Разворачивает игру на весь экран без рамки окна
pygame.RESIZABLE Разрешает тянуть окно за края; при изменении размера приходит событие VIDEORESIZE
pygame.NOFRAME Убирает рамку и кнопки управления окном
pygame.SCALED Масштабирует картинку под разрешение монитора, полезно для пиксель-арта

Есть и удобный трюк: вызов set_mode((0, 0)) создаёт окно размером с текущее разрешение экрана, узнавать его заранее не придётся. Флаги комбинируются через вертикальную черту: pygame.display.set_mode((0, 0), pygame.FULLSCREEN).

pygame.display.set_caption()

Принимает строку и выводит её в заголовок окна. Кириллица работает без дополнительных настроек. Если функцию не вызывать, окно получит подпись по умолчанию «pygame window».

Игровой цикл: почему без него окно закрывается

Если оставить только init() и set_mode(), окно мелькнёт и исчезнет: скрипт дошёл до конца файла, Python завершил процесс, вместе с ним закрылось и окно. Поэтому нужен бесконечный цикл, который не даёт программе завершиться. Как устроен сам оператор, мы подробно разбирали в статье про цикл while в Python.

Внутри цикла каждую итерацию, то есть каждый кадр, происходят три вещи:

  • Обработка событий. pygame.event.get() забирает из очереди всё, что случилось: клики, нажатия клавиш, закрытие окна. Событие pygame.QUIT приходит по клику на крестик, по нему мы выставляем running = False и выходим из цикла.
  • Отрисовка. screen.fill((30, 30, 40)) заливает фон цветом в формате RGB, поверх него вы позже будете рисовать спрайты. pygame.display.flip() выводит готовый кадр на монитор, до этого вызова все изменения существуют только в памяти.
  • Контроль частоты кадров. clock.tick(60) притормаживает цикл так, чтобы он крутился не быстрее 60 раз в секунду. Без этого игра выжмет из процессора все 100% и будет работать с разной скоростью на разных компьютерах.

Кроме flip() существует pygame.display.update(): ему можно передать прямоугольник или список прямоугольников, и он перерисует только их. На первых проектах разница незаметна, начинайте с flip(), он проще и обновляет весь экран целиком.

Шаблон посильнее: константы, выход по Esc и первая фигура

Магические числа вроде (800, 600) прямо в вызовах быстро превращают код в кашу. Размеры окна, частоту кадров и цвета принято выносить в константы в начале файла: поменять разрешение тогда можно одной строкой.

import pygame

WIDTH, HEIGHT = 800, 600
FPS = 60
BG_COLOR = (30, 30, 40)

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Моя первая игра")
clock = pygame.time.Clock()

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False

    screen.fill(BG_COLOR)
    pygame.draw.circle(screen, (255, 200, 0), (WIDTH // 2, HEIGHT // 2), 50)
    pygame.display.flip()
    clock.tick(FPS)

pygame.quit()

Что добавилось по сравнению с минимальным скелетом:

  • Константы WIDTH, HEIGHT, FPS. Размеры и частота кадров задаются в одном месте и переиспользуются по всему коду, например в расчёте центра экрана.
  • Выход по Esc. Событие pygame.KEYDOWN приходит при нажатии любой клавиши, а event.key == pygame.K_ESCAPE отбирает именно Escape. Удобно на этапе отладки, когда окно запускается десятки раз.
  • Первая фигура. pygame.draw.circle() рисует жёлтый круг радиусом 50 пикселей в центре окна. Координаты центра считаются из констант: WIDTH // 2 и HEIGHT // 2.

Этот шаблон уже можно развивать до игры: заменить круг на спрайт, повесить движение на стрелки, добавить счёт. Структура цикла при этом не меняется: события, логика, отрисовка.

Как изменить размер окна после запуска

Размер, заданный в set_mode(), не приговор. Есть два способа его поменять уже в работающей программе.

Способ 1: повторный вызов set_mode(). Функцию можно вызывать сколько угодно раз, каждый вызов пересоздаёт окно с новыми параметрами. Так обычно делают переключение между оконным и полноэкранным режимом по горячей клавише.

Способ 2: флаг RESIZABLE плюс обработка события. Когда пользователь тянет окно за край, PyGame присылает событие VIDEORESIZE с новыми размерами в атрибутах event.w и event.h:

screen = pygame.display.set_mode((640, 480), pygame.RESIZABLE)
...
for event in pygame.event.get():
    if event.type == pygame.VIDEORESIZE:
        screen = pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE)

Текущий размер окна в любой момент возвращает screen.get_size(), он отдаёт кортеж (ширина, высота). Удобно распаковать его в две переменные: w, h = screen.get_size(). Разрешение монитора целиком можно узнать через pygame.display.Info(): атрибуты current_w и current_h после создания окна показывают размеры текущей поверхности, а до создания — экрана.

Ваня БуявецКанал основателя Checkroi Вани БуявцаЗабирайте промпты и обучение по нейросетям в моём Телеграм-каналеБольше 3 700 человек уже применяют Claude Code, ChatGPT и другие нейросети в работе, учёбе, бизнесе и жизниПерейти в канал

Частые ошибки и как их исправить

Пять ситуаций, с которыми сталкивается почти каждый новичок на первом запуске:

Симптом Причина Решение
ModuleNotFoundError: No module named 'pygame' Библиотека не установлена или стоит в другом интерпретаторе Выполнить python -m pip install pygame тем же Python, которым запускаете скрипт
Окно открывается и сразу закрывается Нет игрового цикла, скрипт дошёл до конца и завершился Добавить while running с обработкой событий, как в примере выше
Окно «Не отвечает», курсор крутится В цикле нет pygame.event.get(), очередь событий переполняется, и система считает программу зависшей Каждый кадр вычитывать события циклом for event in pygame.event.get()
Окно есть, но экран чёрный, ничего не рисуется Забыли pygame.display.flip(), кадр остался в памяти Вызывать flip() или update() в конце каждой итерации цикла
pygame.error: video system not initialized Обращение к дисплею после pygame.quit() или до создания окна Проверить порядок вызовов: сначала init() и set_mode(), затем работа с экраном, и только в самом конце quit()

Отдельный совет про имя файла: не называйте свой скрипт pygame.py. Python попытается импортировать ваш же файл вместо библиотеки, и вы получите загадочную ошибку про отсутствие pygame.init.

Где освоить Python системно

Окно и игровой цикл занимают первые 20 строк любой игры, дальше начинаются спрайты, коллизии, звук и архитектура посерьёзнее. Чтобы уверенно расти от скелета до полноценного проекта, понадобится системная база по Python: функции, классы, работа с модулями. Мы собрали каталог курсов по Python с фильтрами по цене и формату, а отдельный roadmap Python-разработчика поможет спланировать путь целиком.

КурсШколаСтоимость со скидкойВ рассрочкуДлитель­ностьОбзор курса от Checkroi
Профессия «Python-разработчик»
Перейти на сайт курса
SkillboxSkillbox157 335 ₽5987 ₽/мес.10 месяцевОбзор курса
Fullstack-разработчик на Python
Перейти на сайт курса
НетологияНетология175 800 ₽7125 ₽/мес.21 месяцОбзор курса
Разработчик на Python
Перейти на сайт курса
НетологияНетология198 000 ₽5500 ₽/мес.6 месяцевОбзор курса
Автоматизированное тестирование на Python
Перейти на сайт курса
SkillboxSkillbox118 666 ₽4108 ₽/мес.9 месяцевОбзор курса
Программирование на Python ПРО
Перейти на сайт курса
SkillboxSkillbox119 600 ₽250 000 ₽/мес.17 месяцевОбзор курса

Больше программ — в полном каталоге курсов по Python

Часто задаваемые вопросы

Что возвращает pygame.init()?

Кортеж из двух чисел: сколько модулей библиотеки запустилось успешно и сколько с ошибкой. В учебных проектах результат обычно не проверяют: если окно создалось, остальные модули почти наверняка в порядке.

Как сделать окно PyGame на весь экран?

Вызовите pygame.display.set_mode((0, 0), pygame.FULLSCREEN). Кортеж (0, 0) автоматически подставляет текущее разрешение экрана, поэтому узнавать его заранее не нужно.

Чем pygame.display.flip() отличается от update()?

flip() перерисовывает весь экран целиком, а update() умеет обновлять только переданные ему прямоугольники, что экономит ресурсы в больших проектах. На первых программах разницы нет, начинайте с flip().

Почему окно PyGame показывает «Не отвечает»?

В игровом цикле нет вызова pygame.event.get(). Очередь событий переполняется, и операционная система решает, что программа зависла. Добавьте обработку событий в каждую итерацию цикла, как в примерах из статьи.

Нужно ли вызывать pygame.quit() в конце программы?

Да. Вызов корректно выгружает модули библиотеки и освобождает ресурсы. Без него в некоторых средах разработки окно может зависать при закрытии, хотя при запуске из терминала процесс завершится и так.

Можно ли задать размеры окна через переменные?

Да, и это хорошая практика: вынесите ширину и высоту в константы WIDTH и HEIGHT в начале файла и передайте их в set_mode((WIDTH, HEIGHT)). Поменять разрешение потом можно одной строкой, а константы пригодятся в расчётах координат.

Читайте Checkroi первым в Google
Добавьте Checkroi в избранные источники — и наши разборы курсов и обзоры школ будут показываться выше в вашей выдаче Google.
Оставить комментарий
0 комментариев
Форма комментария

Оставьте комментарий

Напишите, что думаете. Нам важно ваше мнение!