Skip to content

Latest commit

 

History

History
216 lines (145 loc) · 15.4 KB

File metadata and controls

216 lines (145 loc) · 15.4 KB

Pygame → Web (Браузер)

Краткое руководство: как собрать игру на Pygame в версию для браузера и что нужно для публикации на Яндекс Игры и CrazyGames.


1. Pygame в браузере: не WebGL, а WebAssembly

Игры на Pygame в браузер обычно переносят не в WebGL, а через WebAssembly (WASM):

  • Код Python и Pygame компилируется/запускается в браузере как WASM (через CPython-WebAssembly).
  • Рендер по‑прежнему идёт через Pygame (в браузере это бэкенд на Canvas/WebGL внутри движка), то есть вы не переписываете игру на чистом WebGL.

Основной инструмент: pygbag.


2. Pygbag — сборка Pygame в веб

Установка

pip install pygbag --user --upgrade
# или из репозитория:
pip install git+https://github.com/pygame-web/pygbag --user --upgrade

Сборка игры SpritePro одной командой

Если игра использует SpritePro и в папке проекта есть конфиг webgl.json (размер, заголовок, сцена, список файлов), веб-сборку можно подготовить так:

pip install spritepro[web]
spritepro --webgl путь/к/папке/игры
# или из папки игры:
spritepro --webgl .

Папка сборки по умолчанию: <папка_игры>/web_build. Запуск: python -m pygbag <путь_к_web_build>.

Пример webgl.json в папке игры (минимальный — размер/заголовок/фон подтягиваются из config.py):

{
  "scene_import": "from scene import PingPongScene",
  "scene_var": "PingPongScene",
  "py_files": ["scene.py", "objects.py", "config.py"],
  "extra_setup": ""
}

Размер окна, заголовок и цвет фона можно задать один раз в коде игры — в config.py (или в модуле из config_module в webgl.json). Сборка подставит их в get_screen(...) и update(fill_color=...). Поддерживаемые имена в config: для размера — WINDOW_SIZE, SIZE, SCREEN_SIZE, GAME_SIZE; для заголовка — TITLE, GAME_TITLE, WINDOW_TITLE; для фона — FILL_COLOR, BACKGROUND_COLOR, BG_COLOR. Если задать их в config.py, в webgl.json можно не дублировать size, title, fill_color.

Установка через pip: после pip install spritepro[web] команда spritepro --webgl . копирует пакет из site-packages в папку сборки — поведение такое же, как при разработке в репозитории библиотеки.

Звук в веб-сборке

В браузере Pygbag поддерживает в основном OGG. Файлы MP3/WAV при подготовке сборки исключаются. Подключайте звуки в формате OGG или конвертируйте их для веб-версии.

Минимальные правки в коде

  1. Точка входа — главный файл с игровым циклом должен называться main.py.
  2. Асинхронный цикл — игровой цикл должен быть в async def main() и где‑то внутри содержать await asyncio.sleep(0) (отдаёт управление браузеру).
  3. Запуск — в конце файла: asyncio.run(main()).

Пример минимального main.py:

import asyncio
import pygame

pygame.init()
pygame.display.set_mode((320, 240))
clock = pygame.time.Clock()

async def main():
    while True:
        # ваша логика, отрисовка
        pygame.display.update()
        await asyncio.sleep(0)   # обязательно, аргумент 0
        clock.tick(60)

asyncio.run(main())

Запуск локально

Из каталога выше папки с игрой:

pygbag my_game_folder
# или
python -m pygbag my_game_folder

Открыть в браузере: http://localhost:8000. Первая загрузка может быть долгой (загрузка Python WASM и ассетов).

Сборка для выкладки

  • Только сборка (без локального сервера):
    pygbag my_game_folder --build
  • Самодостаточный HTML с ассетами:
    pygbag my_game_folder --html
  • Архив для загрузки (Яндекс Игры, itch.io, CrazyGames):
    pygbag my_game_folder --archive
    Создаётся, например, build/web.zip.

Через SpritePro CLI (одной командой):

pip install spritepro[web]
spritepro --webgl путь/к/игре --archive

Будет подготовлена веб-сборка и создан ZIP в <папка_сборки>/build/web.zip. В архиве в корне лежит index.html и все файлы билда (JS, WASM, ассеты) — такой формат принимают Яндекс Игры и большинство площадок HTML5-игр.

Ограничения и советы

Что Рекомендация
Аудио Только OGG (сжатый). WAV/MP3/M4A в веб-сборке не подходят. На десктопе можно по sys.platform != "emscripten" подгружать WAV/MP3.
Изображения PNG / WebP / JPG. Избегать сырых форматов (BMP).
Пути Только прямые слэши /, все ассеты внутри папки проекта.
GUI / I/O Не использовать tkinter, синхронные сетевые вызовы и т.п. Для GUI поверх Pygame — pygame-ce, pygame_gui и т.д.
Доп. модули Сложные пакеты (numpy и т.д.) объявлять в PEP 723 в main.py или через доступные wheels для pygbag.
Мультиплеер Встроенный spritePro.networking (TCP-сокеты) в браузере не работает: в WASM нет обычных TCP-сокетов. См. ниже.

Для SpritePro: потребуется адаптировать главный цикл под async def main() и await asyncio.sleep(0), а также проверить, что все ресурсы лежат в папке проекта и используют OGG для звука.

Мультиплеер в браузере

Встроенный мультиплеер SpritePro (NetServer / NetClient, multiplayer.MultiplayerContext) использует TCP-сокеты и потоки. В браузере (Pygbag/WASM) стандартные сокеты недоступны или работают иначе, поэтому такой мультиплеер в веб-сборке работать не будет.

Что использовать для мультиплеера в браузере:

  • WebSocket — подключение к внешнему серверу по wss://. Нужен свой бэкенд (Node.js, Python и т.д.) или сервис (Firebase, PlayFab, Nakama и т.п.), который принимает WebSocket и обменивается сообщениями с клиентами.
  • Вызовы к WebSocket из Python в Pygbag возможны через JS-мост (например, platform.window и свой JS-обёртка над WebSocket) или через библиотеки, поддерживающие WASM/браузер.
  • Или использовать режим без сети в веб-версии (например, if sys.platform == "emscripten": — показывать заглушку «мультиплеер только на десктопе» или офлайн-режим).

3. Публикация на площадках

Площадки принимают HTML5-игры: страница с игрой (часто в iframe), которая загружается по URL. Сборка pygbag как раз даёт такой контент (HTML + JS + WASM + ассеты). Дальше нужно выполнить требования площадки и, при необходимости, встроить их SDK.

3.1. Яндекс Игры

Формат загрузки: архив ZIP, в корне архива — index.html и все необходимые файлы (JS, WASM, данные). Сборка spritepro --webgl . --archive даёт именно такой архив (web_build/build/web.zip).

Обязательно:

  • Подключить Yandex Games SDK в игре (скрипт и вызовы API).
  • Платежи и реклама — только через SDK Яндекса.
  • Авторизация только после явного действия пользователя и с понятным объяснением.
  • Звук должен приглушаться/останавливаться при сворачивании вкладки (desktop и mobile).

Устройства:

  • Мобильные: полноэкранный режим, виртуальная клавиатура для полей ввода, адаптив при смене ориентации, управление жестами (и/или акселерометр), без лишних уведомлений WebGL и долгого контекстного меню по долгому тапу.
  • Десктоп: игровая область масштабируется под окно, соотношение сторон не хуже 1:2, мышь/клавиатура.

Дополнительно: гостевой режим или игра без обязательной авторизации с сохранением прогресса; модерация по заявленным браузерам и ОС (обычно 3–5 рабочих дней).

Интеграция с pygbag: сборка pygbag даёт HTML/JS. SDK Яндекса подключается в шаблоне страницы (кастомный шаблон pygbag --template) или на странице, которая встраивает iframe с игрой. Вызовы SDK — из JavaScript; при необходимости можно вызывать их из Python через JS‑мост (если pygbag/среда это позволяют).

3.2. CrazyGames

Размер и загрузка:

  • Начальная загрузка до первого игрового кадра: ≤ 50 MB (для мобильной главной — ≤ 20 MB).
  • При интеграции SDK размер считают до события «Gameplay start» (момент, когда пользователь уже в игре).
  • Всего: до 250 MB, до 1500 файлов.
  • Внешние файлы: до игрового процесса желательно укладываться в ≤ 20 секунд.

Устройства и браузеры:

  • Работа в Chrome и Edge; Safari проверяется.
  • Удобная работа на Chromebook (4 GB RAM).
  • Управление: мышь, клавиатура, тач (если заявлена мобильная версия).
  • На десктопе — ландшафт; портретные игры допустимы с чёрными полосами или фоном.
  • Только относительные пути к файлам в бандле.

Мобильная версия: в CSS для body добавить отключение выделения и двойного зума, например:

-webkit-user-select: none;
user-select: none;

SDK:

  • Basic Launch (первые 2 недели, без монетизации): достаточно события Gameplay start для замера начальной загрузки.
  • Full Launch: полная интеграция SDK (реклама, события Gameplay start/stop, при необходимости User и Data для аккаунта и сохранений).

Интеграция с pygbag: подключается скрипт CrazyGames SDK в шаблоне или на странице-обёртке; событие «Gameplay start» вызывается из JS в момент, когда игра перешла в игровой экран (при кастомном шаблоне pygbag можно вызывать из Python через JS‑мост при первом кадре геймплея).


4. Практические шаги для SpritePro

  1. Вынести точку входа в main.py с циклом в async def main() и await asyncio.sleep(0) (например, обёртка над текущим s.update()).
  2. Собрать проект через pygbag и проверить в браузере: pygbag <папка_игры>, затем --build / --archive.
  3. Разместить полученный билд на своём хостинге или, например, itch.io (через --archive).
  4. Для Яндекса: зарегистрироваться в Yandex Games, добавить SDK в шаблон/страницу, реализовать паузу звука при сворачивании, адаптив и мобильные требования, отправить на модерацию.
  5. Для CrazyGames: зарегистрироваться как разработчик, интегрировать SDK (минимум — Gameplay start), соблюсти лимиты по размеру и путям, отправить билд на проверку.

Итог: Pygame-игры превращаются в веб не в «чистый WebGL», а в браузерный билд на Pygbag (Python WASM + Pygame). Этого достаточно для площадок в формате HTML5; для Яндекс Игр и CrazyGames нужно дополнительно подключить их SDK и выполнить технические и контентные требования площадки.