Глава 20 · Разработка игр с Pygame

Запускаем Pygame-игру в браузере

pygbag — активно поддерживаемый инструмент сообщества для сборки Pygame-игры в WebAssembly, не официальная часть pygame-ce.

Раздел 20.10 уже упоминал: веб-игра на Pygame попадает в браузер через технологию WebAssembly. Инструмент, который делает эту сборку на практике, называется pygbag — активно поддерживаемый проект сообщества, а не официальная часть самого pygame-ce.

pygbag.txt
pip install pygbag
pygbag moya_igra/

Команда запускает локальный веб-сервер и открывает игру прямо в браузере — удобно для проверки перед публикацией на постоянный хостинг. Обратите внимание: аргумент — это папка проекта, а не отдельный файл.

Файл с игровым циклом обязан называться main.py
pygbag ищет внутри папки проекта строго файл main.py — это имя зашито в сборку, и переименовать его нельзя. Коварство в том, что при другом имени (igra.py, game.py) сборка завершится успешно и без единого предупреждения, но в браузере игра просто не запустится: загрузчик будет искать main.py, которого в собранном архиве нет. Если после сборки страница открывается, но остаётся пустой, — первым делом проверьте имя файла.
pygbag — инструмент сообщества, не часть pygame-ce
Как и с мобильными сборками (раздел 20.13, раздел 20.31), важно понимать границу ответственности: pygbag разрабатывается и поддерживается отдельно от pygame-ce. Он активно развивается и на практике хорошо справляется с типичными 2D-играми на Pygame, но при обновлении версии Pygame стоит перепроверять совместимость с текущей версией pygbag, а не считать её гарантированной навсегда.

Что в вебе устроено иначе

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

Обычный запуск на десктопеСборка через pygbag
Доступ к файловой системеПолныйОграничен песочницей браузера
Главный циклwhile True в вашем кодеАсинхронный, с await asyncio.sleep(0) на каждом кадре
УстановкаТребуется Python и pip installНе требуется — открыл ссылку и играешь
ПроизводительностьРодная скорость процессораМожет отличаться от настольной — стоит измерять на целевом устройстве

Главная практическая разница в коде — цикл игры должен стать асинхронным (async def main() с await asyncio.sleep(0) в конце каждого кадра), чтобы не блокировать поток браузера: pygbag ожидает именно такую структуру программы. Важно, что await здесь добавляется рядом с clock.tick(), а не заменяет его — в примерах самого pygbag ограничение частоты кадров остаётся на месте, а строка с await идёт сразу после него.

Насколько браузерная сборка медленнее настольной, заранее сказать нельзя: это зависит от браузера, устройства игрока и самой игры. Производительность стоит измерять на целевом устройстве, а не закладывать какой-то определённый процент потерь заранее.