Add basic selection and navigation systems

Create and connect locations
Select options and render menus
This commit is contained in:
2022-08-04 17:18:23 +02:00
parent 5afa066a79
commit 0549dc6f2f
9 changed files with 193 additions and 42 deletions

View File

@@ -2,13 +2,47 @@
""" Boar Hunting Simulator 2022"""
import utils.text as Text
from operator import truediv
from data import MenuText as mt
import utils.text as Text
from location.locations import *
from player import Player
from utils.input import Menu, Option
def main():
class Game:
def __init__(self) -> None:
self.player = Player()
#ToDo: move this out of the main file
locations = {
"City": SafeZone(self, "Main city", "You find yourself in the small rural town of Mayberry. \nThe town is quaint and charming, with a population of only a few hundred people. \nIt is surrounded by a thick forest, and the only way to get here is on foot. \nThere are a few shops and businesses around."),
"Forest": Location(self, "the Forest", "You find yourself in a warm and lush oak forest. \nThe dense trees provide plenty of cover from the sun, and the forest floor is carpeted with a thick layer of leaves. \nYou hear the sound of birdsong all around you, and the occasional rustle of small animals in the undergrowth."),
}
locations["City"].connect_location(locations["Forest"])
locations["Forest"].connect_location(locations["City"])
self.current_location = locations["City"]
self.quit = False
self.main()
def retire(self):
Text.type(mt.retire_text)
self.quit = True
def main(self):
Text.type(mt.intro_text, delay=0.01, newline_delay=1.0)
while not self.quit:
print(f"\n[{self.current_location.name}]")
options = [
Option("Test option", lambda: print("Test option selected\n")),
Option("Test option no callback", None),
]
options.extend(self.current_location.options)
Menu("What would you like to do?", options).show()
if __name__ == "__main__":
main()
input()
game = Game()
print("Process exited")
exit(0)

View File

@@ -8,3 +8,7 @@ intro_text = ("Hello and welcome to my little game. \n"
"Because an old friend of you got murdered by one you've sworn yourself to revenge him. \n"
"By killing as many boars as possible. \n\n"
"Please navigate using numbers \n")
retire_text = ("You retire from the game. \n"
"Thank you for playing. \n")

View File

47
src/location/locations.py Normal file
View File

@@ -0,0 +1,47 @@
"""Generic Location"""
from utils.input import Option
import utils.text as Text
import time
class Location:
def __init__(self, game, name: str, description: str) -> None:
super().__init__()
self.name = name
self.description = description
self.options = [Option("Look around", self.look_around)]
self.game = game
def look_around(self) -> None:
Text.type(f"{self.description}\n", 0.01, 0.1)
time.sleep(0.5)
def enter(self) -> None:
print(f"You enter {self.name}.\n")
self.game.current_location = self
time.sleep(0.5)
def connect_location(self, location) -> None:
self.options.append(Option(f"Enter {location.name}", location.enter))
class SafeZone(Location):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self.options.extend([
Option("Check stats", self.check_stats),
Option("Retire", self.game.retire)
])
def check_stats(self) -> None:
player = self.game.player
player.check_stats()
class Shop(Location):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
def look_around(self) -> None:
print(f"You find yourself in a small shop called {self.name}.\n{self.description}")

34
src/player.py Normal file
View File

@@ -0,0 +1,34 @@
import utils.text as Text
class Player(object):
def __init__(self) -> None:
self.name = ""
self.gold = 10
self.score = 0
self.mana = 100
self.health = 100
self.current_location = None
self.consumables = { "health" : 0, "mana" : 0 }
self.gear = { "sword" : 0, "armor" : 0, "shield" : None, "staff" : None }
def check_stats(self):
print("You check your stats.")
print(f"💖 Health: {self.health}")
print(f"✨ Mana: {self.mana}")
print(f"💰 Gold: {self.gold}")
def damage(self, amount: int) -> None:
self.health -= amount
print(f"You take {amount} damage.")
if self.health < 0:
self.die()
def heal(self, amount: int) -> None:
self.health += amount
if self.health > 100:
self.health = 100
print(f"You heal {amount} health.")
def die(self) -> None:
Text.type("You die.")

View File

32
src/utils/input.py Normal file
View File

@@ -0,0 +1,32 @@
"""
Utility to show a seletion menu
"""
import time
class Option(object):
def __init__(self, text: str, callback: callable) -> None:
self.text = text
self.callback = callback
class Menu(object):
def __init__(self, title: str, options: list) -> None:
self.title = title
self.options = options
def show(self) -> int:
print(f"\n{self.title}")
for i, option in enumerate(self.options):
print(f"{i+1}. {option.text}")
time.sleep(0.25)
selected = int(input(f"Select an option [1-{len(self.options)}]: "))
if selected > len(self.options):
print("Invalid option.")
time.sleep(0.5)
self.show()
else:
print("") #Newline for better readability
if self.options[selected-1].callback is not None:
self.options[selected-1].callback()
return selected

View File

@@ -2,7 +2,7 @@
Utilities for text output
"""
import time
import time, sys
def type(text: str, delay: float = 0.05, newline_delay: float = 0.0) -> None:
""" Prints the given text, one character at a time, with a delay between each character.