Создание игр на Python: Основы и работа с файлами

Практический курс по разработке 2D-игр с использованием библиотеки Pygame, охватывающий весь процесс от настройки окружения до финальной сборки. Вы научитесь программировать игровую логику, работать с графикой и правильно управлять файловыми ресурсами проекта.

1. Введение в GameDev на Python: установка инструментов и создание окна приложения

Введение в GameDev на Python: установка инструментов и создание окна приложения

Добро пожаловать в курс «Создание игр на Python: Основы и работа с файлами»! Это первая статья, с которой начнется ваше путешествие в мир разработки игр (GameDev). Мы не просто напишем код, мы научимся создавать интерактивные миры, управлять графикой и работать с файловой системой вашего компьютера.

Многие популярные игры и прототипы создавались на Python. Благодаря библиотеке Pygame, этот язык стал отличным выбором для новичков, желающих понять, как работают игры «под капотом», не отвлекаясь на сложную архитектуру движков вроде Unity или Unreal Engine.

Подготовка рабочего места

Прежде чем мы начнем творить, нам нужно подготовить инструменты. Для создания игр нам понадобятся две основные вещи: интерпретатор Python и библиотека Pygame.

1. Установка Python

Скорее всего, Python у вас уже установлен. Проверить это можно, открыв терминал (командную строку) и введя команду:

Если вы видите версию 3.6 или выше — отлично. Если нет, скачайте последнюю версию с официального сайта python.org.

2. Установка Pygame

Pygame — это набор модулей Python, предназначенных для написания видеоигр. Она включает в себя работу с компьютерной графикой и звуком. Установка производится через менеджер пакетов pip.

Откройте терминал и введите:

Если вы работаете на macOS или Linux, возможно, вам потребуется использовать pip3 вместо pip.

Структура проекта и «регистрация» файлов

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

Игра — это не один файл с кодом. Это сложная система, где код должен «знать», где лежат его ресурсы. Создадим правильную структуру папок для нашего курса:

  • Создайте папку с названием игры, например MyFirstGame.
  • Внутри создайте файл main.py — это будет точка входа в игру.
  • Создайте папку assets (ресурсы).
  • Внутри assets создайте папки images (изображения) и sounds (звуки).
  • Такая структура позволяет легко обращаться к файлам. Когда мы будем загружать картинку, мы укажем путь относительно главного файла, например: assets/images/player.png. Это и есть процесс «регистрации» пути к файлу в коде.

    !Структура файлов проекта для правильной организации ресурсов игры

    Первая программа: Создание окна

    Любая игра начинается с окна. Это ваш холст. Давайте напишем код, который просто открывает окно и не закрывается сразу же.

    Откройте main.py и напишите следующий код:

    Давайте разберем, что здесь происходит, шаг за шагом.

    Инициализация и настройка

    Строка pygame.init() запускает все внутренние модули Pygame. Без этой команды библиотека не сможет работать с графикой или звуком.

    Функция pygame.display.set_mode((WIDTH, HEIGHT)) создает графическое окно. Обратите внимание, что размеры передаются в двойных скобках — это кортеж (tuple).

    Игровой цикл (Game Loop)

    Это самая важная концепция в разработке игр. В отличие от обычных программ, которые выполняют задачу и закрываются, игра работает в бесконечном цикле.

    Этот цикл повторяется десятки раз в секунду. Каждый проход цикла называется кадром (frame). Внутри цикла происходят три вещи:

  • Обработка событий: Нажал ли игрок кнопку? Подвинул ли мышь? Нажал ли крестик закрытия окна?
  • Обновление состояния: Изменились ли координаты персонажа? Уменьшилось ли здоровье?
  • Отрисовка: Рисование всего на экране заново.
  • !Схематичное изображение работы игрового цикла

    Система координат в Pygame

    Чтобы рисовать объекты, нужно понимать, как компьютер видит экран. В школе на уроках математики мы привыкли к декартовой системе координат, где растет вверх. В компьютерной графике все иначе.

    Начало координат находится в левом верхнем углу экрана.

    * Ось направлена вправо. * Ось направлена вниз.

    Если мы хотим поместить объект в центр экрана, нам нужно рассчитать его координаты. Формула для центра по оси выглядит так:

    где — искомая координата центра по горизонтали, а — ширина экрана.

    Соответственно, для оси :

    где — искомая координата центра по вертикали, а — высота экрана.

    > Понимание того, что увеличивается при движении вниз — одна из самых частых сложностей для новичков. Если вы хотите, чтобы персонаж подпрыгнул (двигался вверх), вам нужно уменьшать его координату .

    Цвета и заливка экрана

    Пока наше окно просто черное. Давайте закрасим его. В компьютерах цвета обычно кодируются в формате RGB (Red, Green, Blue).

    Это три числа от 0 до 255, указывающие интенсивность красного, зеленого и синего каналов.

    * — Черный * — Белый * — Красный * — Зеленый * — Синий

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

    Команда pygame.display.flip() (или pygame.display.update()) «переворачивает» экран. Компьютер рисует кадр в памяти, а эта команда показывает готовый кадр пользователю. Без нее вы увидите только черный экран, даже если нарисовали шедевры.

    Частота кадров (FPS)

    Чтобы игра работала с одинаковой скоростью на мощных и слабых компьютерах, нужно контролировать FPS (Frames Per Second — кадры в секунду).

    Время одного кадра рассчитывается как:

    где — время в секундах, отведенное на один кадр, а — желаемое количество кадров в секунду.

    Если , то на один кадр у компьютера есть примерно 0.016 секунды (16 миллисекунд). В Pygame для этого используется объект pygame.time.Clock.

    Добавим его в код:

    Итоговый код урока

    Вот полный код вашего первого приложения, которое создает окно, заливает его цветом и корректно закрывается:

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

    2. Архитектура игрового цикла, обработка событий и управление частотой кадров

    Архитектура игрового цикла, обработка событий и управление частотой кадров

    В предыдущей статье мы успешно установили инструменты и создали наше первое окно. Однако, пока что оно статично и «мертво». Чтобы превратить это окно в игру, нам нужно вдохнуть в него жизнь. В мире разработки игр (GameDev) «сердцем» любого проекта является игровой цикл (Game Loop).

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

    Что такое игровой цикл?

    Обычные программы часто работают линейно: запустились, выполнили вычисления, выдали результат и закрылись. Игры работают иначе. Они должны постоянно обновлять картинку на экране, проверяя, нажал ли игрок кнопку, сдвинулся ли враг и не столкнулся ли мяч со стеной.

    Игровой цикл — это бесконечный цикл while, который выполняется десятки раз в секунду. Каждый проход этого цикла называется кадром или тиком.

    !Визуализация трех основных фаз игрового цикла, которые повторяются бесконечно.

    Архитектура правильного игрового цикла всегда состоит из трех последовательных этапов:

  • Обработка событий (Process Input): Мы «слушаем» клавиатуру, мышь или геймпад.
  • Обновление состояния (Update): Мы меняем координаты объектов, проверяем столкновения, уменьшаем здоровье и так далее.
  • Отрисовка (Render): Мы рисуем всё на экране в новых позициях.
  • Почему порядок важен?

    Если вы сначала нарисуете персонажа, а потом измените его координаты, игрок увидит старую позицию до следующего кадра. Это создаст ощущение задержки (лага). Поэтому логика всегда должна предшествовать отрисовке.

    Этап 1: Обработка событий

    Компьютер постоянно получает сигналы от устройств ввода. Pygame складывает эти сигналы в специальную очередь событий. Если мы не будем разбирать эту очередь, операционная система решит, что программа зависла.

    В прошлом уроке мы использовали такой код:

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

    Типы событий

    Существует два основных подхода к проверке нажатий:

  • Единичное нажатие (Event): Срабатывает один раз в момент опускания клавиши. Идеально для прыжка, выстрела или открытия меню.
  • Удержание клавиши (State): Проверяет, зажата ли клавиша прямо сейчас. Идеально для движения персонажа.
  • Пример обработки единичных нажатий внутри цикла событий:

    Этап 2: Обновление состояния (Логика)

    Здесь происходит вся магия. Допустим, у нас есть координаты квадрата и . Чтобы он двигался вправо, нам нужно каждый кадр увеличивать .

    Математически это выглядит так:

    где — новая координата объекта, — текущая координата, а — скорость (velocity) движения за один кадр.

    Давайте реализуем движение квадрата. Но сначала вспомним про файлы. В курсе мы говорим о работе с файлами, и здесь есть золотое правило:

    > Никогда не загружайте файлы внутри игрового цикла.

    Чтение с жесткого диска — очень медленная операция. Если вы напишете image = pygame.image.load("player.png") внутри цикла while, ваш компьютер будет пытаться читать файл 60 раз в секунду. Это убьет производительность. Все ресурсы (картинки, звуки) загружаются и «регистрируются» в переменных до начала цикла while.

    Пример простой логики движения:

    Обратите внимание: здесь мы используем pygame.key.get_pressed(). Это проверка состояния (удержания), а не события. Пока вы держите стрелку вправо, player_x будет увеличиваться.

    Этап 3: Отрисовка (Render)

    Экран компьютера — это не чистый лист, который сам очищается. Это набор пикселей, которые хранят свой цвет, пока их не перекрасят. Если мы нарисуем квадрат в новой позиции, но не сотрем его в старой, мы получим «шлейф».

    Поэтому этап отрисовки всегда начинается с заливки фона.

    Алгоритм художника

    В Pygame порядок команд рисования определяет слои. То, что написано в коде позже, будет нарисовано поверх предыдущего. Если вы сначала нарисуете персонажа, а потом фон (screen.fill), персонаж будет перекрыт фоном и вы его не увидите.

    Управление частотой кадров (FPS)

    Представьте, что вы запустили игру на старом ноутбуке, и цикл успевает прокрутиться 30 раз в секунду. А ваш друг запустил её на мощном игровом ПК, где цикл крутится 200 раз в секунду.

    Если скорость персонажа player_speed = 5 пикселей за кадр, то:

    * На ноутбуке: пикселей в секунду. * На мощном ПК: пикселей в секунду.

    На мощном компьютере игра будет работать слишком быстро, и играть будет невозможно. Чтобы этого избежать, нам нужно ограничить FPS (Frames Per Second).

    Для этого используется объект pygame.time.Clock.

    Математика времени кадра

    Когда мы задаем FPS, мы фактически определяем время, отводимое на один кадр. Формула выглядит так:

    где — время одного кадра в секундах, а — целевая частота кадров.

    Если , то:

    Это значит, что у компьютера есть всего около 16 миллисекунд, чтобы обработать события, обновить координаты всех врагов и нарисовать картинку. Если компьютер не успевает, игра начинает «тормозить» (FPS падает).

    Полный пример: Управляемый квадрат

    Давайте соберем всё вместе в рабочий код. Этот пример демонстрирует правильную архитектуру.

    Заключение

    Мы создали надежный каркас. Теперь вы понимаете, почему персонажи двигаются, почему экран не мерцает и зачем нам нужен clock.tick. Мы также усвоили важное правило работы с файлами: загружать их нужно до цикла, чтобы не перегружать процессор.

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

    3. Работа со спрайтами, анимация персонажей и игровая физика

    Работа со спрайтами, анимация персонажей и игровая физика

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

    Сегодня мы перейдем от абстрактных квадратов к настоящей игровой графике. Мы разберем понятие спрайта, научимся анимировать движения и реализуем базовую физику столкновений. Также мы продолжим тему работы с файлами, так как правильная загрузка изображений — ключ к производительности.

    Что такое спрайт?

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

    В библиотеке Pygame для работы со спрайтами существует специальный класс pygame.sprite.Sprite. Использование этого класса, вместо простого рисования картинок, дает нам огромные преимущества:

  • Группировка: Мы можем объединить всех врагов в одну группу и обновлять их одной командой.
  • Встроенная физика: У спрайтов есть готовые методы для проверки столкновений.
  • Организация кода: Каждый объект становится самостоятельным классом со своим поведением.
  • Загрузка изображений и работа с файловой системой

    Прежде чем создать спрайт, нам нужно загрузить изображение с жесткого диска. В первой статье мы создали папку assets/images. Допустим, у нас там лежит файл hero.png.

    Чтобы загрузить его в память, используется функция:

    Однако, просто загрузить картинку недостаточно. В Pygame изображения хранятся в определенном формате пикселей. Если формат картинки не совпадает с форматом экрана, компьютер будет тратить ресурсы на конвертацию при каждой отрисовке кадра. Это сильно снижает FPS.

    Поэтому после загрузки всегда нужно вызывать методы оптимизации:

    * .convert() — для изображений без прозрачности (фоны). * .convert_alpha() — для изображений с прозрачностью (персонажи, предметы).

    Правильный код загрузки:

    Создание класса игрока

    Давайте создадим класс для нашего героя, унаследовав его от pygame.sprite.Sprite. В этом классе обязательно должны быть два атрибута: self.image (как выглядит объект) и self.rect (где он находится и какие у него границы).

    Метод update запускается каждый кадр игрового цикла. Вся логика движения должна быть внутри него.

    Анимация персонажа

    Статичная картинка, скользящая по экрану, выглядит скучно. Анимация — это быстрая смена нескольких изображений (кадров), создающая иллюзию движения.

    !Схематичное представление спрайт-листа для анимации бега.

    Чтобы реализовать анимацию, нам нужен список изображений вместо одного self.image.

    Математика смены кадров

    Главная проблема анимации — скорость. Игровой цикл работает со скоростью 60 кадров в секунду (FPS). Если мы будем менять картинку каждый кадр цикла, персонаж будет дергаться слишком быстро. Нам нужно менять картинку, например, каждые 10 кадров игры.

    Для расчета текущего кадра анимации можно использовать формулу:

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

    В коде это часто реализуется проще — через накопление времени или счетчик:

    Игровая физика: Столкновения (Collisions)

    Физика в играх начинается с вопроса: «Коснулись ли эти два объекта?». Самый простой и быстрый способ проверки — AABB (Axis-Aligned Bounding Box). Это проверка пересечения двух прямоугольников, стороны которых параллельны осям координат.

    Именно для этого у каждого спрайта есть атрибут self.rect. Pygame делает всю математику за нас.

    Проверка столкновений в коде

    Допустим, у нас есть группа спрайтов mobs (враги) и спрайт player (игрок).

    Функция pygame.sprite.spritecollide возвращает список всех спрайтов из группы mobs, которые пересеклись с player.

    Если мы хотим сделать подбор монеток, мы изменим третий аргумент на True:

    Группы спрайтов

    Чтобы код был чистым, мы не обновляем и не рисуем каждый объект вручную. Мы добавляем их в группы.

    Теперь наш игровой цикл становится невероятно лаконичным:

    Итоговый пример

    Объединим знания. Создадим программу, где спрайт игрока (зеленый квадрат) управляется стрелками, а спрайты врагов (красные квадраты) падают сверху. При столкновении игра закрывается.

    > Для упрощения кода мы будем использовать цветные квадраты вместо загрузки картинок, но принцип работы с self.image и self.rect остается тем же.

    Заключение

    Мы сделали огромный шаг вперед. Теперь вы умеете создавать объекты, наделять их поведением, анимировать их и заставлять взаимодействовать друг с другом. Использование классов и групп спрайтов — это профессиональный подход, который позволит вам создавать сложные игры, не запутываясь в коде.

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

    4. Регистрация файлов: правильная загрузка изображений, звуков и сохранение прогресса

    Регистрация файлов: правильная загрузка изображений, звуков и сохранение прогресса

    Добро пожаловать на четвертый урок курса «Создание игр на Python»! В прошлых статьях мы создали окно, запустили игровой цикл и даже заставили спрайты двигаться и сталкиваться. Но наша игра всё ещё выглядит «немой» и забывчивой: в ней нет звуков, а рекорд сбрасывается при каждом перезапуске.

    Сегодня мы займемся файловой системой. Мы научимся грамотно указывать пути к файлам (то, что мы назвали «регистрацией»), добавим звуковое сопровождение и реализуем систему сохранения прогресса. Это превратит ваш прототип в полноценное приложение.

    Проблема путей: Абсолютные и Относительные

    Новички часто совершают одну и ту же ошибку: указывают полный путь к файлу на своем компьютере. Например:

    Этот код будет работать у вас, но как только вы отправите игру другу, она сломается. У друга нет пользователя Ivan и папки MyGame на рабочем столе. Чтобы игра работала везде, нужно использовать относительные пути.

    Модуль os

    Python имеет встроенную библиотеку os, которая позволяет программе узнать, где она находится, и строить пути от этой точки. Это и есть процесс «регистрации» базовой директории.

    Функция os.path.join автоматически подставит правильный разделитель папок: слэш / для Linux/macOS или обратный слэш \ для Windows. Это делает вашу игру кроссплатформенной.

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

    Продвинутая работа с изображениями

    Мы уже упоминали методы .convert() и .convert_alpha(). Давайте разберем, почему они критически важны для производительности, через математику памяти.

    Когда вы загружаете изображение, оно занимает определенный объем видеопамяти. Объем памяти , необходимый для хранения одного кадра изображения без сжатия, рассчитывается по формуле:

    где — объем памяти в битах, — ширина изображения в пикселях, — высота изображения в пикселях, а — глубина цвета (количество бит на пиксель, обычно 32 для RGBA).

    Если формат загруженного изображения (например, PNG) отличается от формата экрана, процессору приходится конвертировать каждый пиксель в каждом кадре. При 60 FPS это миллионы операций в секунду.

    * convert(): Используйте для фонов и объектов без прозрачности. Это самый быстрый формат отрисовки. * convert_alpha(): Используйте для персонажей и объектов с прозрачностью (альфа-каналом).

    Управление прозрачностью (Color Key)

    Иногда у вас есть спрайт на черном или белом фоне, но без альфа-канала (например, старые спрайты в формате BMP или JPG). Чтобы сделать фон прозрачным, используется метод set_colorkey.

    Добавляем звук и музыку

    Звук в играх делится на две категории:

  • Звуковые эффекты (SFX): Короткие звуки (выстрел, прыжок, взрыв). Они хранятся в памяти целиком и могут проигрываться одновременно.
  • Музыка: Длинные треки. Они читаются с диска потоком (stream), так как загружать 5-минутный трек в оперативную память нерационально.
  • Для работы со звуком в Pygame используется модуль pygame.mixer.

    Загрузка звуковых эффектов

    Лучший формат для эффектов — WAV (несжатый звук) или OGG. Формат MP3 для эффектов использовать не рекомендуется из-за возможных задержек при декодировании.

    Загрузка фоновой музыки

    Для музыки отлично подходят форматы MP3 и OGG.

    Сохранение прогресса: Чтение и запись файлов

    Представьте, что игрок набрал 1000 очков. Если он закроет игру, этот результат исчезнет. Чтобы этого не произошло, нам нужно записать данные в файл.

    Самый простой способ — использовать текстовый файл .txt. Более профессиональный подход — формат JSON, так как он позволяет хранить сложные структуры данных (словари, списки).

    Пример: Система рекордов (High Score)

    Для начала создадим файл highscore.txt в папке игры и напишем туда число 0.

    #### Чтение рекорда при запуске игры

    Конструкция with open(...) — это контекстный менеджер. Он гарантирует, что файл будет закрыт сразу после чтения, даже если произойдет ошибка. Это «золотой стандарт» работы с файлами в Python.

    #### Запись нового рекорда

    В конце игры (или при выходе) мы проверяем, побил ли игрок рекорд.

    Режим 'w' (write) означает запись. Внимание: этот режим полностью стирает старое содержимое файла перед записью. Если вы хотите дописать данные в конец (например, лог событий), используйте режим 'a' (append).

    Использование JSON для сложных сохранений

    Если нужно сохранить не только очки, но и уровень, здоровье и инвентарь, лучше использовать модуль json.

    Итоговая структура загрузчика ресурсов

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

    Пример простой организации:

    Заключение

    Теперь ваша игра умеет «общаться» с внешним миром: загружать графику и звук из правильных папок и запоминать достижения игрока.

    Мы разобрали:

  • Использование os.path.join для создания надежных путей.
  • Разницу между Sound (эффекты) и music (фон).
  • Сохранение данных через простые файлы и JSON.
  • В следующей статье мы займемся созданием пользовательского интерфейса (UI): добавим меню, кнопки и вывод текста на экран прямо во время игры.

    5. Обработка столкновений, подсчет очков и создание исполняемого файла игры

    Обработка столкновений, подсчет очков и создание исполняемого файла игры

    Приветствую вас на финальном уроке курса «Создание игр на Python: Основы и работа с файлами»! Мы проделали большой путь: от установки Python и создания пустого окна до управления анимированными спрайтами и сохранения прогресса в файлы.

    Сегодня мы превратим наш прототип в полноценный программный продукт. Мы углубимся в математику столкновений, научимся выводить текст (счет и меню) на экран, а в конце совершим магию — упакуем ваш код и все ресурсы (картинки, звуки) в один .exe файл, который можно отправить друзьям, даже если у них не установлен Python.

    Продвинутая обработка столкновений

    В третьем уроке мы использовали pygame.sprite.spritecollide для проверки пересечения прямоугольников (AABB). Это быстро и просто, но не всегда точно. Если ваш персонаж круглый (например, мяч или планета), прямоугольная зона вокруг него будет регистрировать столкновения там, где визуально пустота.

    Столкновения на основе радиуса

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

    !Сравнение прямоугольной (AABB) и радиальной моделей столкновений

    Математически расстояние между двумя точками и вычисляется по теореме Пифагора:

    где — искомое расстояние, — координаты центра первого объекта, — координаты центра второго объекта, а — операция извлечения квадратного корня.

    В Pygame для этого есть встроенная функция pygame.sprite.collide_circle. Чтобы она работала, у ваших спрайтов должен быть задан атрибут radius.

    Добавление четвертого аргумента pygame.sprite.collide_circle меняет алгоритм проверки с прямоугольников на круги.

    Интерфейс пользователя (UI): Вывод текста

    Игра без счета — это просто интерактивная заставка. Нам нужно показать игроку, сколько очков он набрал. В Pygame текст не пишется напрямую на экран, он сначала «рендерится» (превращается) в картинку, а затем эта картинка накладывается на экран.

    Работа со шрифтами

  • Загрузка шрифта: Можно использовать системный шрифт или загрузить свой файл .ttf.
  • Создание поверхности (Surface): Превращение строки текста в изображение.
  • Отрисовка (Blit): Копирование изображения текста на главный экран.
  • Теперь внутри игрового цикла, в блоке отрисовки, мы можем вызвать:

    Логика завершения игры (Game Over)

    Когда игрок проигрывает, игра не должна просто закрываться. Она должна показать экран «Game Over» и предложить сыграть снова. Для этого нам нужна переменная состояния.

    Такая структура позволяет легко управлять потоком игры.

    Создание исполняемого файла (.exe)

    Это самый важный момент для распространения вашей игры. Ваши друзья вряд ли захотят устанавливать Python и библиотеки через консоль, чтобы поиграть. Мы упакуем всё в один файл.

    Для этого мы будем использовать библиотеку PyInstaller.

    Шаг 1: Установка PyInstaller

    Откройте терминал и введите:

    Шаг 2: Проблема путей к файлам (Критически важно!)

    Помните, мы учились использовать os.path.join для регистрации файлов? При компиляции в .exe возникает нюанс. PyInstaller распаковывает ваши картинки и звуки во временную папку _MEIPASS где-то в недрах системы Windows/Linux. Ваш код должен уметь находить эту папку.

    Нам нужно написать специальную функцию для определения пути к ресурсам:

    Теперь везде, где вы загружали картинки, используйте эту функцию:

    Если вы пропустите этот шаг, ваш .exe файл создастся, но при запуске вылетит с ошибкой FileNotFoundError.

    Шаг 3: Сборка проекта

    Теперь, когда пути настроены правильно, перейдите в терминале в папку с вашим файлом main.py и введите команду:

    Разберем флаги этой команды:

    * --onefile: Собрать всё в один единственный .exe файл (иначе будет папка с кучей файлов). * --noconsole: При запуске игры не будет появляться черное окно консоли (идеально для GUI приложений). * --add-data "assets;assets": Самая важная часть. Она говорит: «Возьми папку assets рядом со скриптом и положи её внутрь .exe под именем assets». Примечание для macOS/Linux:* Вместо точки с запятой ; используйте двоеточие : (например, "assets:assets").

    !Как PyInstaller упаковывает код и ресурсы в один файл

    После завершения процесса (это может занять минуту) в вашей папке появится директория dist. Внутри неё будет лежать ваш заветный main.exe.

    Заключение курса

    Поздравляю! Вы прошли путь от чистого листа до готового дистрибутива игры.

    Мы изучили:

  • Основы Pygame: создание окна и игровой цикл.
  • Спрайты: классы, группы и анимация.
  • Физику: движение и столкновения (AABB и радиус).
  • Файловую систему: правильную загрузку ресурсов, сохранение рекордов и упаковку в EXE.
  • Теперь у вас есть фундамент. Дальше вы можете изучать создание меню, добавление уровней, частиц (particles), шейдеров и сетевого режима. Но база, которую вы получили здесь — это 90% успеха любого 2D-проекта на Python.

    Удачи в разработке ваших миров!