Implement menumanager v1

This commit is contained in:
Matyáš Caras 2022-03-24 18:20:39 +01:00
parent 2240dd0c0b
commit efaf74111b
7 changed files with 88 additions and 80 deletions

8
.vscode/launch.json vendored
View file

@ -5,12 +5,12 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Start with example game", "name": "Python: Start main",
"type": "python", "type": "python",
"request": "launch", "request": "launch",
"program": "${workspaceRoot}/__main__.py", "program": "${workspaceFolder}/__main__.py",
"args": ["./example.yml"], "console": "integratedTerminal",
"console": "integratedTerminal" "justMyCode": true
} }
] ]
} }

View file

@ -1,7 +1,7 @@
from genericpath import isdir from genericpath import isdir
from lib.game import * from lib.game import *
from colorama import init, Back, Fore from colorama import init, Back, Fore
from os import mkdir, listdir from os import mkdir, listdir, path
def lang(): def lang():
lang = "en" lang = "en"
@ -35,16 +35,15 @@ def main(): # TODO: Maybe a menu for available text games?
except Exception as e: except Exception as e:
print(f"{Back.RED}{Fore.RED}{l['error_loading']} {file}:") print(f"{Back.RED}{Fore.RED}{l['error_loading']} {file}:")
print(e) print(e)
# PRINT OUT GAME SELECT # PRINT OUT GAME SELECT
# TODO SWITCH TO MENU MANAGER
print(" TEXTY ")
print(l['available'])
if len(games) < 1: if len(games) < 1:
print(l['no_games']) print(l['no_games'])
else: else:
for i,g in enumerate(games): names = []
print(f"{i} - {g.name}") for n in games: names.append(n.name)
print(f"{len(games)} - {l['quit']}") m = MenuManager(names,f" TEXTY \n{l['available']}")
games[m.selected].main_menu()
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -1,11 +1,13 @@
import yaml import yaml
from yaml.loader import SafeLoader from yaml.loader import SafeLoader
from colorama import Fore, Back, Style from colorama import Fore, Back
import re import re
from lib.menu import MenuManager
from .save import SaveManager from .save import SaveManager
from .ascii import AsciiAnimation from .ascii import AsciiAnimation
from time import sleep from time import sleep
from os import system, path, mkdir from os import system
class Game: # the game class keeps information about the loaded game class Game: # the game class keeps information about the loaded game
def __init__(self,data:dict): def __init__(self,data:dict):
@ -23,85 +25,48 @@ class Game: # the game class keeps information about the loaded game
l = self.save.load() l = self.save.load()
if not l: if not l:
# New game # New game
print(self.name) m = MenuManager([self.lang['start'],self.lang['options'],self.lang['quit']],f"{self.name}\n{self.lang['game_by'].replace('$author',self.author)}")
print(self.lang['game_by'].replace("$author",self.author)) selection = m.selected
print("")
print(f"1 - {self.lang['start']}")
print(f"2 - {self.lang['options']}")
print(f"0 - {self.lang['quit']}")
selection = self.make_selection(3)
system("cls||clear") system("cls||clear")
if(selection == 1): # start new game if(selection == 0): # start new game
self.print_text() self.print_text()
elif(selection == 2): elif(selection == 1):
self.settings_menu() self.settings_menu()
elif(selection == 0): elif(selection == 2):
print(self.lang['quitting']) print(self.lang['quitting'])
exit() exit()
else: # Display continue else: # Display continue
print(self.name) m = MenuManager([self.lang['continue'],self.lang['new_name'],self.lang['options'],self.lang['quit']],f"{self.name}\n{self.lang['game_by'].replace('$author',self.author)}")
print(self.lang['game_by'].replace("$author",self.author)) selection = m.selected
print("")
print(f"1 - {self.lang['continue']}")
print(f"2 - {self.lang['new_name']}")
print(f"3 - {self.lang['settings']}")
print(f"0 - {self.lang['quit']}")
selection = self.make_selection(3)
system("cls||clear") system("cls||clear")
if(selection == 1): if(selection == 0):
self.current = self.save.currentPrompt self.current = self.save.currentPrompt
self.inventory = self.save.inventory self.inventory = self.save.inventory
self.print_text() self.print_text()
elif(selection == 2): elif(selection == 1):
self.print_text() self.print_text()
elif(selection == 3): elif(selection == 2):
self.settings_menu() self.settings_menu()
elif(selection == 0): elif(selection == 3):
print("Quitting") print(self.lang['quitting'])
exit() exit()
def settings_menu(self): # displays the settings menu def settings_menu(self): # displays the settings menu
print("Options") m = MenuManager([self.lang['lang'],self.lang['back']],self.lang['options'])
print("") selection = m.selected
print(f"1 - {self.lang['lang']}") if(selection == 0):
print("0 - Back") m = MenuManager(["English","Česky",self.lang['back']],self.lang['lang'])
selection = self.make_selection(1) selection = m.selected
if(selection == 1):
print(self.lang['lang'])
print("")
print("1 - English")
print("2 - Česky")
print(f"0 - {self.lang['back']}")
selection = self.make_selection(2)
system("cls||clear") system("cls||clear")
if(selection == 1): if(selection == 0):
with open("./saves/lang","w") as f: with open("./saves/lang","w") as f:
f.write("en") f.write("en")
elif(selection == 2): elif(selection == 1):
with open("./saves/lang","w") as f: with open("./saves/lang","w") as f:
f.write("cz") f.write("cz")
self.settings_menu() self.settings_menu()
else: else:
self.main_menu() self.main_menu()
def make_selection(self, length=0) -> int: # this method makes sure a valid selection is made and returns the selection as a number
# TODO: replace with selection by keyboard(?)
l = length # sets the length
if(l == 0): # if no length was set, we get it from nodes
l = len(self.nodes[self.current]["actions"])-1
y = False
selection = 0
# TODO: Check for "has_item"
while y == False: # while the selection is not correct
try:
selection = int(input(self.lang['selection'])) # ask for selection
except ValueError: # handle wrong input type
print(self.lang['not_number'])
if(selection > l or selection < 0): # if the number is bigger than the length or smaller than 0, print error
print(self.lang['invalid'])
else:
y = True # else return the selection
return selection
def print_text(self): # Prints out the current prompt def print_text(self): # Prints out the current prompt
system("cls||clear") system("cls||clear")
@ -109,22 +74,27 @@ class Game: # the game class keeps information about the loaded game
if(animated != None): if(animated != None):
self.print_animated(animated.group(0)) self.print_animated(animated.group(0))
self.nodes[self.current]["text"] = self.nodes[self.current]["text"].replace("{"+animated.group(0)+"}","") # remove the animated text from the text prompt self.nodes[self.current]["text"] = self.nodes[self.current]["text"].replace("{"+animated.group(0)+"}","") # remove the animated text from the text prompt
print(self.parse_colors(self.nodes[self.current]["text"]))
print("")
ostring = ""
if("actions" in self.nodes[self.current].keys()): if("actions" in self.nodes[self.current].keys()):
for i,option in enumerate(self.nodes[self.current]["actions"]): actions_desc = []
ostring+=f"{i} - {self.nodes[option]['description']}\n" for option in self.nodes[self.current]["actions"]:
print(ostring) try:
sel = self.make_selection() actions_desc.append(self.nodes[option]["description"])
except:
print(f"{Back.RED}{Fore.WHITE}{self.lang['no_action'].replace('$action',option)}{Fore.RESET}")
exit(1)
m = MenuManager(actions_desc,self.parse_colors(self.nodes[self.current]["text"]))
sel = m.selected
if "add_item" in self.nodes[self.current]: # if there is an add_inventory key in the node, if "add_item" in self.nodes[self.current]: # if there is an add_inventory key in the node,
# add item to inventory # add item to inventory
self.inventory.append(self.nodes[self.current]["add_inventory"]) self.inventory.append(self.nodes[self.current]["add_inventory"])
self.current = self.nodes[self.current]["actions"][sel] self.current = self.nodes[self.current]["actions"][sel]
self.save.currentPrompt = self.current # save the current prompt self.save.currentPrompt = self.current # save the current prompt
self.print_text() self.print_text()
else:
print(self.parse_colors(self.nodes[self.current]["text"]))
print("")
def print_animated(self,animid): # prinst the first found occurence of an ascii animation def print_animated(self,animid): # prints the first found occurence of an ascii animation
animation = AsciiAnimation() animation = AsciiAnimation()
animation.load_ascii(animid) animation.load_ascii(animid)
for frame in animation.frames: for frame in animation.frames:

View file

@ -20,3 +20,4 @@ not_number: 'Nezadali jste číslo'
invalid: 'Neplatný výběr' invalid: 'Neplatný výběr'
error_loading: 'Při načítání YAML souboru nastala chyba:' error_loading: 'Při načítání YAML souboru nastala chyba:'
no_action: 'Chyba: žádná akce "$action" nenalezena v souboru hry'

View file

@ -20,3 +20,4 @@ not_number: 'Not a number selection'
invalid: 'Invalid selection' invalid: 'Invalid selection'
error_loading: 'An exception has occured while loading the game from the YAML file' error_loading: 'An exception has occured while loading the game from the YAML file'
no_action: 'Error: No action "$action" found in the game file.'

View file

@ -1,6 +1,43 @@
from os import system
import keyboard import keyboard
from colorama import Fore
class MenuManager: # TODO class MenuManager:
def __init__(self,selections:list): '''
Creates text menus controllable with arrow keys
'''
def __init__(self,selections:list,additional:str):
self.selected = 0 # current selection self.selected = 0 # current selection
self.selections = selections # available selections self.selections = selections # available selections
self.additional = additional # additional text to display above the menu
keyboard.add_hotkey("up",self.up)
keyboard.add_hotkey("down",self.down)
keyboard.add_hotkey("enter",self.make_selection)
self.show_menu()
input()
def make_selection(self) -> int:
keyboard.remove_all_hotkeys()
def up(self):
if self.selected == 0:
self.selected = len(self.selections)-1
else:
self.selected -= 1
system("cls||clear")
self.show_menu()
def down(self):
if self.selected == len(self.selections)-1:
self.selected = 0
else:
self.selected += 1
system("cls||clear")
self.show_menu()
def show_menu(self):
print(self.additional)
for selection in self.selections:
if(self.selected == self.selections.index(selection)):
print(f"{Fore.RED}->{Fore.RESET} {selection}")
else:
print(f" {selection}")