Квест в консоли на Python. Часть 2
Итак, продолжаем продолжаем писать квест в консоли на языке Python. Первая часть описана здесь. В ней мы реализовали автоматическую загрузку и сохранение состояния прохождения квеста. Сейчас же займемся (начнем по крайне мере) отрисовкой локации, и реакцией на нажатые кнопки. В локации предусмотрим возможность отображения картинки из ASCII. Например json стартовой локации может выглядеть примерно так:
1 2 3 4 5 6 7 8 9 10 11 |
{ "title": "Стартовая локация", "description": "Стартовая локация описание", "ascii_art": " __ ================================\n ALCATRAZ /__\\ || ||<(.)>||<(.)>|| || \n ____________| | || _|| || ||_ || \n |_|_|_|_|_|_| | || (__D || C__) || \n |_|_|_|_|_|_|__| || (__D || C__) ||\n A@\\|_|_|_|_|_|/@@Aa || (__D || C__) ||\n aaA@@@@@@@@@@@@@@@@@@@aaaA || (__D || C__) ||\n A@@@@@@@@@@@DWB@@@@@@@@@@@@A || || || || dwb||\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ================================", "available_locations": { "left": 1, "right": 2, "forward": 3, "back": 4 } } |
Создадим класс TLocation, при инициалиизации будем передавать в него инициализированный класс player. В переменной класса data — будем хранить загруженную локацию.
1 2 3 4 5 6 7 8 9 10 11 |
class TLocation: data = {} player={} stdscr=curses.initscr() scr_size=stdscr.getmaxyx() def __init__(self,player): self.player=player; def load_location(self, location): f = open("locations/" + str(location) + ".json", mode='r', encoding='utf-8') self.data = json.load(f) f.close() |
Далее нарисуем верхнее меню, где сообщаем игроку, на какие локации он может перемещаться, и что он держит в руках:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
def top_menu(self): loc="Идти: " if "left" in self.data["available_locations"]: loc=loc+"влево(4) " if "right" in self.data["available_locations"]: loc=loc+"вправо(6) " if "forward" in self.data["available_locations"]: loc=loc+"вперед(8) " if "back" in self.data["available_locations"]: loc=loc+"назад(2) " curses.start_color() curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK) self.stdscr.addstr(1, 1, loc,curses.color_pair(1)) curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK) self.stdscr.addstr(1, 1, loc,curses.color_pair(1)) # что в руках hands = "В руках: " self.stdscr.addstr(2, 1, "") for object in self.player.data["in_hands"]: hands=hands+"["+object+"]" if len(self.player.data["in_hands"])==0: hands = hands+"ничего нет" self.stdscr.addstr(2, 1, hands, curses.color_pair(1)) |
Ну и собственно основной код отрисовки локации, включающий бесконечный цикл ожидания нажатий клавиатуры. Предусматриваем переход на другую локацию, выход из игры и сохранение игры.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
def location_view(self, location): self.load_location(location) self.stdscr.clear() self.stdscr.border() self.top_menu() # рисуем верхнее меню # название локации curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK) x = int((self.scr_size[1] - len(self.data["title"])) / 2) self.stdscr.addstr(2, x, self.data["title"],curses.color_pair(2)) # рисуем рисунок ежели он есть y=3 if "ascii_art" in self.data: mass_art=self.data["ascii_art"].split("\n") i=0 while i<len(mass_art): x=int((self.scr_size[1]-len(mass_art[i]))/2) self.stdscr.addstr(y+i, x, mass_art[i]) i+=1 y = y + len(mass_art); # Выводим описательную часть curses.init_pair(3, curses.COLOR_CYAN, curses.COLOR_BLACK) self.stdscr.addstr(y, 1, self.data["description"],curses.color_pair(3)) # Выводим нижнее меню curses.init_pair(4, curses.COLOR_RED, curses.COLOR_BLACK) self.stdscr.addstr(y + 1, 1, "Осмотреться вокруг [v] Применить что в руках [h]", curses.color_pair(4)) self.stdscr.addstr(y + 2, 1, "Выйти из квеста [q] Сохранить состояние [r]", curses.color_pair(4)) self.stdscr.refresh() while True: key=self.stdscr.getch() print(key) # реализация перехода с локации на локацию if key==52 and "left" in self.data["available_locations"]: self.player.data["location"]=self.data["available_locations"]["left"] self.location_view(self.player.data["location"]) if key==54 and "right" in self.data["available_locations"]: self.player.data["location"]=self.data["available_locations"]["right"] self.location_view(self.player.data["location"]) if key==56 and "forward" in self.data["available_locations"]: self.player.data["location"]=self.data["available_locations"]["forward"] self.location_view(self.player.data["location"]) if key==50 and "back" in self.data["available_locations"]: self.player.data["location"]=self.data["available_locations"]["back"] self.location_view(self.player.data["location"]) if key == 114: self.player.save() #self.message("Внимание!","Состояние прохождения завершено. \nФайл находится в папке /saves") if key==113: curses.reset_shell_mode() curses.endwin() exit(0) print(self.data) |
В результате картинка (квест в консоли) на мониторе выглядит уже чуть симпатичнее: