Часть 1. НАЧАЛО.


Итак, я решил сделать игру-рогалик(RPG) на Python практически с нуля! Решение принято после того, как я обшарил весь интернет в поисках open-source проекта или мануала, на котором можно основать свою игру. Нашлись либо огромные проекты с миллионом файлов и кода, либо еле-рабочие игры, где можно только ходить по карте. В этом блоге я, шаг за шагом, создам полноценную игру: с вещами, инвентарем, NPC, монстрами и прочими элементами любой нормальной RPG-игры.

Нам понадобятся:

  • Python 3
  • PyGame (pip install pygame)
  • Скачать и разархивировать архив
Начнём с простейшей PyGame-игры, с минимальными функциями рисования карты и ходьбы: 
MinimalPyGame.zip - скачайте этот .zip-файл разархивируйте куда угодно. 

Там всего 1 каталог и 3 файла:
  1. /assets/ каталог → картинки с тайлами, объектами и персонажами.
  2. /utils.py → функции разрезания картинок на отдельные объекты и кадры для анимаций.
  3. /models.py классы для работы игры.
  4. /roguelike.py → сама игра, с минимальным простеньким кодом.
Эта игра сделана под Python 2.7, но мы будем работать с Python 3 версией, поэтому для начала, исправим две строки в файле utils.py:
except pygame.error, message:
#заменяем на:
except pygame.error as message:
Найдите все строки, соответствующие первой строке в указанном выше блоке кода. Замените все эти строки на нижний вариант, который выделен чёрным фоном. 
Всё, после замены запятой на as, игра будет запускаться под Python 3 без ошибок.

Далее в уроках, внутри блоков кода, я таким же образом буду выделять чёрным фоном те строки, которые нужно добавить или изменить. 



Краткое описание работы кода игры:

В самом начале файла roguelike.py мы видим две матрицы клеток для карты игры:
tileData  это стены, которые непроходимы для персонажа(являются коллизиями). Стены находятся в тех клетках, где указано 'W'.
decorationData  декораций, на данный момент там есть только "ceiling" - "потолок". Позиции декораций в матрице клеток обозначены символами 'c'.
Пустые клетки обозначены пробелом '  '    это пол, по которому ходит персонаж.


Далее идет функция
def loadTextures():
...   

В этой функции загружаются картинки из каталога /assets/ и режутся на тайлы(клетки) с указанным размером в пикселях. Например, множество тайлов для пола помещается в список floorTextures[], путем вырезания квадратиков 16x16 пикселей из tileset-картинки 'assets/floor.png'


Потом функция
def loadLevel(tileData, decorationData, outputLevel):
...   
В этой функции создаются объекты классов(объявленных в models.py) при помощи матриц decorationData[y][x] и tileData[y][x], описанных ранее. Причем для заполнения поля клеточек(тайлов) игры, каждый раз используются случайные тайлы, выбранные из картинок-asset'ов при помощи функции choice(...), которая выбирает случайный тайл из созданного ранее множества.


Ну а затем главная функция
def main():
...  

В которой устанавливается размер окна игры, заголовок, и начинается главный бесконечный цикл игры
while True:
...  

Каждый раз выполнения этого цикла - это кадр игры. 
Первая строка clock.tick(24) делает так, чтобы FPS(количество кадров в секунду) было не более 24 в секунду.

Затем проверяются нажатые кнопки на клавиатуре (K_RIGHT, K_LEFT, K_DOWN, K_ESCAPE...), чтобы менять координаты персонажа на каждом кадре бесконечного цикла, делая возможным перемещение персонажа стрелками на клаве.

Далее идет цикл, проходящий по всем координатам x,y игровой карты
for y in range(0, 16):
    for x in range(0, 16):
...  
в нём функция screen.blit(...) накладывает картинку персонажа, а также созданные тайлы для игровой карты на поверхность screen(класс pygame.Surface). Всё это завершается функцией pygame.display.flip(), которая наконец выводит созданную поверхность screen в окно игры на текущем кадре.

В существующем коде уже реализованы коллизии(столкновения) персонажа со стенами, но криво... В будущих уроках мы это исправим.


Вносим первые изменения в игру.

Для начала изменим внешний вид персонажа, сменив противного зеленого гоблина на лучника в плаще. Для этого в файле roguelike.py меняем 'goblin' на 'ranger'
...

from models import Level, Tile, Entity

playerType = 'ranger'
gameScale = 2
tileData = [

... 
В оригинальном архиве игры уже есть заранее готовые картинки с spritesheet'ами персонажей в каталоге /assets: cleric.png, orc.png, skeleton.png, warrior.png, wizard.png и др.
 Существующий код сам подцепит нужный файл /assets/rogue.png, и у нас появится лучник вместо зеленого гоблина.

Теперь сменим унылый серый пол на зеленую траву. Tileset-картинка для тайлов пола, которая режется на тайлы функцией loadSpritesheet(...), называется 'assets/floor.png'. Чтобы сменить пол на траву, нужно перерисовать эту картинку, что я уже заранее сделал в Фотошопе.
Сохраняем мою картинку с травой прямо из блога: 
скачать tileset-картинку травы.
Переименуйте её в floor.png и положите в /assets/ игры, заменив существующий файл с таким же именем. В результате серый пол сменится на траву.

Ну и напоследок, уберем нелепый черный столб внизу экрана игры, который образован выделенными ниже символами 'W' и 'c' в массивах decorationData и tileData:

заменяем 'W' и 'c', поставив на их места пробелы '  '



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



Посмотреть и скачать отдельные файлы этого урока можно в Github-каталоге.

Архив .zip со всеми рабочими файлами: LESSON-1.BEGIN.zip
 
Если что-то не ясно, пишите и спрашивайте в комментариях к посту в Блоге или в Discord, постараюсь всем ответить.

Комментарии в этом Блоге без регистрации, можно писать анонимно.

Комментарии

  1. Норм. Жду когда начнёшь перепиливать под себя.

    ОтветитьУдалить
  2. Спасибо за подробное описание

    ОтветитьУдалить
  3. Извините, да, очень хороший гайд

    ОтветитьУдалить

Отправить комментарий