WIP saves and languages

This commit is contained in:
Matyáš Caras 2022-02-04 19:35:38 +01:00
parent 5cf11374f4
commit 0e6858f566
7 changed files with 106 additions and 22 deletions

View file

@ -1,5 +1,5 @@
# texty # texty
An extremely simple text-adventure game engine(?) An extremely simple text-adventure game ~~engine(?)~~ player
## What is this? ## What is this?
I was bored I was bored

View file

@ -11,7 +11,7 @@ def main(): # TODO: Maybe a menu for available text games?
game = load(argv[1]) game = load(argv[1])
if(game is None): if(game is None):
exit(1) exit(1)
game.print_text() game.main_menu()
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View file

@ -1,5 +1,6 @@
meta: # make sure every key is in lowercase meta: # make sure every key is in lowercase
name: "My Text Adventure" # Game name name: "My Text Adventure" # Game name
id: "examplegame" # An original game ID (please try to be original)
creator: "hernik" # Your name as a creator creator: "hernik" # Your name as a creator
game: # here goes all the game logic game: # here goes all the game logic

View file

@ -2,21 +2,80 @@ import yaml
from yaml.loader import SafeLoader from yaml.loader import SafeLoader
from colorama import Fore, Back, Style from colorama import Fore, Back, Style
import re import re
from .save import SaveManager
from .ascii import AsciiAnimation from .ascii import AsciiAnimation
from time import sleep from time import sleep
from os import system from os import system, path, mkdir
class Game: class Game: # the game class keeps information about the loaded game
def __init__(self,data:dict): def __init__(self,data:dict):
self.name = data["meta"]["name"] self.name = data["meta"]["name"]
self.author = data["meta"]["creator"] self.author = data["meta"]["creator"]
self.current = "start" self.current = "start"
self.nodes = {} self.nodes = {}
self.inventory = [] self.inventory = []
self.save = SaveManager()
self.id = data["meta"]["id"]
for k in data["game"]: for k in data["game"]:
self.nodes.update({k:data["game"][k]}) self.nodes.update({k:data["game"][k]})
def make_selection(self) -> int: def main_menu(self): # displays the main menu
l = self.save.load()
if not l:
# New game
print(self.name)
print(f"A game by {self.author}")
print("")
print("1 - Start")
print("2 - Options")
print("0 - Quit")
else: # Display continue
print(self.name)
print(f"A game by {self.author}")
print("")
print("1 - Continue")
print("2 - New game")
print("3 - Options")
print("0 - Quit")
selection = self.make_selection(3)
system("cls||clear")
if(selection == 1):
self.current = self.save.currentPrompt
self.inventory = self.save.inventory
self.print_text()
elif(selection == 2):
self.print_text()
else:
print("Quitting")
exit()
def settings_menu(self): # displays the settings menu
print("Settings")
print("")
print("1 - Language")
print("0 - Back")
selection = self.make_selection(1)
if(selection == 1):
print("Language")
print("")
print("1 - English")
print("2 - Czech")
print("0 - Back")
selection = self.make_selection(2)
system("cls||clear")
if(selection == 1):
with open("./saves/lang","w") as f:
f.write("en")
elif(selection == 2):
with open("./saves/lang","w") as f:
f.write("cz")
self.settings_menu()
pass
def make_selection(self, length=0) -> int: # this method makes sure a valid selection is made and returns the selection as a number
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"])
y = False y = False
selection = 0 selection = 0
# TODO: Check for "has_item" # TODO: Check for "has_item"
@ -31,10 +90,7 @@ class Game:
y = True y = True
return selection return selection
def print_text(self): def print_text(self): # Prints out the current prompt
'''
Used to print out the current prompt with the options
'''
animated = re.search(r"(?!{).+(?=})",self.nodes[self.current]["text"]) # find the animated text animated = re.search(r"(?!{).+(?=})",self.nodes[self.current]["text"]) # find the animated text
if(animated != None): if(animated != None):
self.print_animated(animated.group(0)) self.print_animated(animated.group(0))
@ -51,14 +107,10 @@ class Game:
# 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.nodes[self.current]["actions"][sel] # save the current prompt
self.print_text() self.print_text()
def print_animated(self,animid): def print_animated(self,animid): # prinst the first found occurence of an ascii animation
'''
Used to print out animated text,
currently only prints out the first occurence of an animated text
(in curly braces)
'''
animation = AsciiAnimation() animation = AsciiAnimation()
animation.load_ascii(animid) animation.load_ascii(animid)
for frame in animation.frames: for frame in animation.frames:
@ -67,22 +119,28 @@ class Game:
sleep(animation.speed) sleep(animation.speed)
print() print()
def parse_colors(self,text:str) -> str: # Converts color codes into terminal colors
def parse_colors(self,text:str) -> str:
'''
Used to convert color codes in string to colors from the colorama lib
'''
newText = text.replace("&b",Fore.CYAN).replace("&c",Fore.RED).replace("&e", Fore.YELLOW).replace("&a",Fore.GREEN).replace("&9",Fore.BLUE).replace("&r",Fore.RESET).replace("&f",Fore.WHITE).replace("&5",Fore.MAGENTA).replace("\n",Fore.RESET + "\n") # replace color codes and newlines with colorama newText = text.replace("&b",Fore.CYAN).replace("&c",Fore.RED).replace("&e", Fore.YELLOW).replace("&a",Fore.GREEN).replace("&9",Fore.BLUE).replace("&r",Fore.RESET).replace("&f",Fore.WHITE).replace("&5",Fore.MAGENTA).replace("\n",Fore.RESET + "\n") # replace color codes and newlines with colorama
newText += Fore.RESET # reset color at the end of the text newText += Fore.RESET # reset color at the end of the text
return newText return newText
def load(file_path): def load(file_path): # starts to load the game from YAML
'''Loads the game from a YAML file to a Game class''' lang = "en"
if not (path.exists("./saves/lang")):
mkdir("./saves")
with open("./saves/lang","w") as f:
f.write("en")
else:
with open("./saves/lang","r") as f:
lang = f.read()
if lang == "cz":
lang = "cz"
try: try:
with open(file_path) as f: with open(file_path) as f:
data = yaml.load(f,Loader=SafeLoader) data = yaml.load(f,Loader=SafeLoader)
g = Game(data) g = Game(data)
g.lang = lang
return g return g
except Exception as e: except Exception as e:
print(f"{Back.RED}{Fore.WHITE}An exception has occured while loading the game from the YAML file:{Fore.RESET}{Back.RESET}") print(f"{Back.RED}{Fore.WHITE}An exception has occured while loading the game from the YAML file:{Fore.RESET}{Back.RESET}")

1
lib/lang/cz.yml Normal file
View file

@ -0,0 +1 @@
TODO: "todo"

1
lib/lang/en.yml Normal file
View file

@ -0,0 +1 @@
TODO: "todo"

23
lib/save.py Normal file
View file

@ -0,0 +1,23 @@
from os import path
import yaml
class SaveManager: # manages save and configuration files
def __init__(self):
self.id = ""
self.currentPrompt = ""
self.lang = ""
self.inventory = []
def load(self):
if(path.exists(f"./saves/{self.id}.yml")):
with open(f"./saves/{self.id}.yml",encoding="utf-8") as f:
data = yaml.load(f,Loader=yaml.SafeLoader)
self.currentPrompt = data["currentPrompt"]
self.inventory = data["inventory"]
return True
return False
def save(self):
data = {"id":self.id,"currentPrompt":self.currentPrompt,"inventory":self.inventory,"lang":self.lang}
with open(f"./saves/{self.id}.yml",mode="w",encoding="utf-8") as f:
yaml.dump(data,f)