Мой опыт создания полноценного 2D-платформера на Python в 2023
Говорят, что на Python легко и просто создавать платформеры. Правда ли?
Предисловие
Все мы были когда-то детьми. И те, кто вырос в 90-ые, наверняка играли в приставку Денди (в США она называлась NES — Nintendo Entertainment System). Среди всех игр была одна игра, которая мне особенно запомнилась, так как была не похожа на все остальные. Это игра The Addams Family (1992 год, студия Ocean). В игре была какая-то своя атмосфера. И мне захотелось создать что-то похожее.
Придумываем сюжет и геймплей
Сюжет в игре будет очень простым: мы купили поместье викторианской эпохи, и когда туда приехали, нам очень сильно захотелось заснуть. При этом мы обратили внимание, что повсюду разбросаны детали некоторого механизма. Проблема в том, что дверь в поместье закрыта и нам надо найти ключи. Ходим ищем ключи от дверей, собирая детали, а когда открываем двери ищем кровать, чтобы поспать. Видим очень странные сны, в которых также собираем предметы, уклоняясь от врагов и шипов. И в конце находим проблему этого поместья.
Рисуем ассеты
Перед тем как приступить к созданию ассетов (разных картинок, которые потом можно будет анимировать), надо разобраться в каком разрешении будет работать игра. У всех разные мониторы с разным разрешением. И не у всех даже FullHD. Поэтому выбираем 720p — то есть разрешение 1280х720 пикселей. Для такого разрешения органично будут смотреться плитки земли размером 64х64 пикселя. Берем любой векторный графический редактор и начинаем рисовать.

Рисовал как мог, вспоминая как у всех ребят в школе по рисованию было «5», и только у меня одного «4». Вы могли заметить, что это все статические объекты, которые не имеют анимации. Ну а как же с анимированными объектами? Все просто, анимированные объекты — это те же отдельные картинки, у которых изменяется положение некоторых пикселей. Вот пример анимации на примере главного героя игры:

Собственно программирование
Инструмент для создания игр мы будем выбирать на основании того языка программирования, который более-менее знаем. В моем случае, это Python. Выбираем какую-нибудь современную версию языка — я выбрал Python 3.11.4. Для создания игр на Python существует библиотека Pygame. Причем это не графический движок типа Unity. Здесь нет графического интерфейса, а есть только набор разных классов, в которых есть свои атрибуты и методы. Эта библиотека служит для осуществления манипуляции графическими объектами на основе событий (events).
Заполняем словарики
Игру начинаем даже не с файла main.py, а с файла settings.py, куда будут прописаны основные параметры и настройки игры. Помимо названия игры, длины и ширины окна игры, мы должны прописать доступы к ассетам. В связи с тем, что данных много, а в Python есть такой тип данных как словарь (dict), в основе которого лежит хеш-таблица, мы выбираем именно словарь и заполняем. Фрагмент такого словаря:
12: {
'style': 'enemy',
'type': 'tile',
'menu': 'enemy',
'menu_surf': 'images/menu/bug.png',
'preview': 'images/preview/bug.png',
'graphics': 'images/enemies/cementry/bug'
},
С чего начинается родина — с main.py
Наконец-то поработаем с main.py. Конечно, будем использовать нашу любимую концепцию ООП. Есть такая штука как принципы SOLID, которым следует придерживаться при разработке программы. Некоторые из них я собираюсь нарушить, но вот один я никак нарушить не могу — буковка “S” — Single Resposibility Principle. Суть его в том, что каждый класс должен выполнять строго обозначенную функцию и быть ограниченным своей задачей. Не надо создавать классы, которые делают все сразу. Поэтому main.py будет класс Main, в котором есть главный цикл игры — бесконечный цикл с условием While, но все события будут обрабатываться в других отдельных классах, а в Main мы будем создавать экземпляры этих других классов.
Режим редакторы игры
Как думаете, что объединяет такие игры как Heroes of Might and Magic 3, The Elder Scrolls III: Morrowind и Max Payne. Их объединяет, что на диске с ними шел встроенный редактор уровней. Это мощнейший инструмент в разработке игры. Беда в том, что в Pygame ничего подобного нет, а значит мы его сами создадим. Здесь лучше найти какой-нибудь туториал. Я лично нашел на YouTube видео немецкого программиста Christian Koch “Creating a Mario Maker style game in Python” (канал ClearCode). На основе этого видео и создаем редактор уровней. Но нам надо как-нибудь сохранять те произведения искусства, которые мы создали. И здесь у нас есть выбор: либо сохранять как текстовый формат передачи данных (например, JSON), или же сохранять в бинарном виде, используя библиотеку pickle. Я решил, что для уровней у нас будут бинарные файлы, а для сохранений в процессе игры у нас будет JSON.

Параллельно с режимом редакторов уровней у нас есть отдельный класс Level, в экземпляр которого будут передаваться данные из редактора. И все механики будут тестироваться в именно в экземпляре класса Level.
Коллизии и анимации спрайтов
Спрайт в Pygame — это графическое изображение, которое представляет собой одну единицу анимации. Главное здесь — это коллизии и анимации. С коллизиями все просто — у классов Pygame есть встроенные методы для работы с коллизиями, например, collidepoint. Для анимаций в соответствующем классе мы создадим свой метод и используем тернарный оператор:
def animate(self, dt):
self.frame_index += ANIMATION_SPEED * dt
self.frame_index = 0 if self.frame_index >= len(
self.animation_frames) else self.frame_index
self.image = self.animation_frames[int(self.frame_index)]
Мы просто перебираем картинки в списке, и вызываем их одну за другой с помощью переменной self.frame_index. Тернарый оператор применяется, чтобы из бежать ошибки IndexError: list index out of range.
Обратите внимание на константу ANIMATION_SPEED. Дело в том, что у нас разлочен FPS в игре и скорость анимации никак не зависит от FPS.
Главное меню игры
Не помню какой обзорщик из YouTube 10-ых годов говорил, что главное меню — это как вешалка в театре. Для меня очень удобным было меню из игры The Elder Scrolls V: Skyrim — ничего лишнего. Нечто похожее и мы сделаем с учетом, что я не умею рисовать и игру мы делаем на Pygame. В главном меню мы должны сказать игроку как управлять персонажем в игре и создать возможности поменять язык, перейти в полноэкранный режим, уменьшить или увеличить громкость музыки и звуков, и перейти в режим редактора.
Музыкальная пауза
Если для звуков полно бесплатных ресурсов, где можно скачать free sounds, то музыку я решил сам написать для игры. Все рождается из импровизации. Записываем все на листочек, а потом ноты перебиваем в любой музыкальный midi-редактор, который поддерживает нотный стан.
Вот пример трека Garden из моей игры:

Как видно, самый обычный соль-мажор и нисходящие, восходящие гармонии. Остается все это записать на своем синтезаторе Casio из детства, немного обработать и саундтрек готов.
Итоги
Самое главное, что я понял, создание игры — это хорошая возможность прокачать ваши hard skills. Процесс создания игры заставляет вас решать множество задач. Библиотека Pygame — это один из самых лучших способов понять концепцию ООП в Python. Я, когда неправильно прописал условия для звуков и музыки, понял, как именно загружаются в память компьютера экземпляры классов, как в них инициализируются атрибуты и как работают методы. Также вы повторите весь базовый синтаксис Python — работу со всеми типами данных, включая файлы, и со стандартными библиотеками типа math, random, configparser, json и pickle.
Полный код игры доступен на моем GitHub
На GitHub разблочен режим редакторов уровней и имеет полный функционал, а в архиве с игрой этот функционал ограничен в плане рисования и сохранений.
В PlatinumGames заявили о сильном желании продолжить развитие серии Bayonetta
В студии Supermassive Games прошла волна сокращений
Съёмки «Бэтмена. Часть 2» приостановили по семейным обстоятельствам Мэтта Ривза
Marvel выпустила новый постер фильма «Мстители: Доктор Дум»
Директор Final Fantasy VII Revelation объяснил решение выпустить игру на дисках
Джеймс Ганн уже работает над фильмом, который выйдет после «Человека завтрашнего дня»
Для Warhammer Age of Sigmar представили памятную миниатюру Королевы войны Темной Клятвы
Продюсер оценил шансы сериала «Ходячие мертвецы: Мёртвый город» на четвёртый сезон как высокие