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

@@ -1,2 +1,2 @@
# Boar hunting simulator
# Boar hunting simulator
### Inspired by MrxGamers small boar hunting game

View File

@@ -1,14 +1,48 @@
#!/usr/bin/env python3
""" Boar Hunting Simulator 2022"""
import utils.text as Text
from data import MenuText as mt
def main():
Text.type(mt.intro_text, delay=0.01, newline_delay=1.0)
if __name__ == "__main__":
main()
input()
#!/usr/bin/env python3
""" Boar Hunting Simulator 2022"""
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
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__":
game = Game()
print("Process exited")
exit(0)

View File

@@ -1,10 +1,14 @@
"""
Text for menus
"""
intro_text = ("Hello and welcome to my little game. \n"
"You are a villager living in a small village. \n"
"There are many wild boars lurking outside that are making the passage difficult for everyone to travel. \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")
"""
Text for menus
"""
intro_text = ("Hello and welcome to my little game. \n"
"You are a villager living in a small village. \n"
"There are many wild boars lurking outside that are making the passage difficult for everyone to travel. \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

@@ -1,19 +1,19 @@
"""
Utilities for text output
"""
import time
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.
Arguments:
text: The text to be printed.
delay: The delay between each character. (Default 0.05)
newline_delay: The delay between each newline. (Default 0.0)
"""
for char in text:
print(char, end="", flush=True)
if (char == "\n"):
time.sleep(newline_delay)
"""
Utilities for text output
"""
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.
Arguments:
text: The text to be printed.
delay: The delay between each character. (Default 0.05)
newline_delay: The delay between each newline. (Default 0.0)
"""
for char in text:
print(char, end="", flush=True)
if (char == "\n"):
time.sleep(newline_delay)
time.sleep(delay)