Как стать автором
Обновить

Используем PyInstaller для создания exe-файла игры на Pygame

Я, как и многие новички в создании игр, столкнулся с проблемой как поделиться готовым проектом с друзьями, у которых не установлен Python.

На недостаток обучалок по созданию игр на Pygame не пожалуешься, но мне не удалось найти подробной инструкции как собрать единый exe-файл, для запуска которого не требуется держать рядом папку с изображениями и игровыми звуками.

Из множества библиотек, собирающих проекты в exe, выбрал PyInstaller. Его оказалось достаточно, чтобы справиться с задачей. Опишу все пошагово (для Windows).

Установка PyInstaller

В командной строке пишем:

pip install pyinstaller

Создание spec-файла (файла спецификации)

Pyinstaller создает приложение, выполняя содержимое файла спецификации.

Чтобы создать spec-файл, через командную строку в папке с проектом набираем:

pyi-makespec --onefile mygame.py

Флаг --onefile создает файл спецификации, который позволит упаковать всё необходимое в один exe-файл.

Получаем файл mygame.spec

Редактирование spec-файла

Теперь нужно правильно настроить spec-файл. Открываем spec-файл в текстовом редакторе.

block_cipher = None

a = Analysis(['mygame.py'],
             pathex=['C:/Users/1/Desktop/Python/test'],
             binaries=[],
             datas=[('Images/image.png', 'Images'), 
             ('Music/track.mp3', 'Music'), 
             ('font.ttf', '.')],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='mygame',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=False, icon='C:/Users/1/Desktop/Python/test/icon.ico')

В качестве первого атрибута для объекта класса Analysis передается имя py-файла, который нужно скомпилировать.

Атрибут pathex отвечает за путь к папке проекта.

В списке datas указываются файлы, которые нужно загрузить для работы приложения (изображения, музыка/звуки, шрифты). Datas — это список кортежей. Каждый кортеж имеет два элемента строкового типа:

  • Первый — путь до файла, который нужно загрузить.
  • Второй указывает имя папки для хранения файла во время выполнения программы
    ('.' — означает, что файл будет помещен во временную папку без подкаталога).

В экземпляре класса EXE редактируем:
name — имя exe-файла.
console — отвечает за то, будет ли вызываться консоль при запуске приложения (True) или нет (False).
icon — содержит путь к иконке игры.

Редактирование путей к файлам в коде

В коде до загрузки файлов необходимо добавить функцию, которая позволит программе найти необходимые для работы файлы независимо от своего расположения (подсмотрено тут).

def resource_path(relative):
    if hasattr(sys, "_MEIPASS"):
        return os.path.join(sys._MEIPASS, relative)
    return os.path.join(relative)

При запуске приложения PyInstaller распаковывает данные во временную папку и сохраняет путь к ней в переменной среды _MEIPASS.

Функция resource_path проверяет создана ли временная папка, и если да, то возвращает путь к ней для дальнейшей загрузки файлов. В противном случае (например, если запустить код через интерпретатор) функция вернет тот путь, который в неё передали (то есть путь к папке проекта с игрой).

Чтобы получить путь к файлу

  • если файл лежит в той же папке, что и py-файл, пишем:

path = resource_path('image.png')

  • если файл вынесен в отдельную папку проекта, пишем:

path = resource_path(os.path.join('Folder', 'image.png'))

При этом, если файл вынесен в отдельную папку проекта, то и во временной папке нужно создавать соответствующий подкаталог (см. редактирование параметра datas).

Далее загружаем файл:

img = pygame.image.load(path)

С музыкой и шрифтами аналогично.

Создание exe

В командной строке вводим:

pyinstaller mygame.spec

Готово! Exe-файл находится в папке dist.

Замечание про функции quit() и exit()
Если в коде вашей игры в качестве функций выхода используются quit() или exit(), то скомпилированное приложение работать не будет.

Эти функции включены, чтобы новичкам было проще ориентироваться в коде, и предназначены только для использования в интерпретаторе. На самом деле для их корректной работы требуется загрузить модуль site.

Стандартным способом выйти из программы является использование sys.exit().

Более подробно здесь.
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.