Глава 20 · Разработка игр с Pygame
Как работает игровой цикл: ввод, обновление и отрисовка
Базовая модель игрового цикла в этой книге — три повторяющиеся фазы: обработать ввод, обновить состояние, нарисовать кадр.
В разделе 20.2 вы уже написали игровой цикл — но теперь, зная контекст всей главы, стоит назвать его части точными именами. Для наших Pygame-игр мы используем базовую модель: любой цикл в этой книге, от простейшего мяча до финального проекта, состоит из трёх повторяющихся фаз.
Input
pygame.event.get()
pygame.key.get_pressed()
↓
Update
изменить координаты
проверить столкновения
обновить счёт
↓
Render
screen.fill(...)
нарисовать всех персонажей
pygame.display.flip()
и снова с начала — десятки раз в секунду
↓Ждать до следующего кадра
clock.tick(FPS)
Порядок фаз важен: ввод обрабатывается раньше обновления состояния (иначе персонаж
реагирует на клавишу с опозданием на кадр), а обновление — раньше отрисовки (иначе на экране
окажется прошлый, ещё не обновлённый кадр). В разделе 20.26 эти три фазы станут тремя
методами класса Game.
У больших движков схема сложнее
Input → Update → Render — надёжная база для учебных и небольших проектов, но не единственно возможная схема. Крупные игровые движки нередко используют фиксированный шаг физики отдельно от частоты кадров экрана, несколько разных фаз обновления (например, отдельно логику и отдельно анимацию), интерполяцию между кадрами для более плавной картинки, очереди событий с приоритетами и иногда несколько потоков выполнения. Здесь эти усложнения намеренно не нужны — трёх фаз достаточно, чтобы понять принцип, а к более сложным схемам можно вернуться позже, когда проект их действительно потребует.
Забыли pygame.init()
pygame.init() не единственный способ инициализировать Pygame — можно инициализировать нужные модули по отдельности, — но в проектах этой книги мы всегда начинаем настройку с него: это удобный способ разом инициализировать все модули, которым нужна инициализация. Если его пропустить, часть модулей (в первую очередь звук) не будет готова к работе, а сообщения об ошибке иногда указывают не на место, где не хватает pygame.init(), а на совершенно другую строку — где Pygame впервые понадобился неинициализированный модуль.Очередь событий не обработана — окно "зависает"
Операционная система считает окно зависшим, если оно долго не забирает свои события из очереди —
pygame.event.get() должен вызываться каждый кадр, даже если внутри цикла for event in ... вы ничего не делаете с большинством событий. Пропуск этого вызова на несколько секунд — частая причина пометки "Не отвечает" в заголовке окна.Практика: три фазы игрового цикла
Pygame открывает нативное окно Python — выполните локально в VS Code, PyCharm или Jupyter
Практика выполняется локально