squirrel-battle/dungeonbattle/game.py

135 lines
4.3 KiB
Python

from random import randint
from typing import Any, Optional,Generator
import json
import os
from .entities.player import Player
from .enums import GameMode, KeyValues, DisplayActions
from .interfaces import Map
from .settings import Settings
from . import menus
from typing import Callable
class Game:
map: Map
player: Player
display_actions: Callable[[DisplayActions], None]
def __init__(self) -> None:
"""
Init the game.
"""
self.state = GameMode.MAINMENU
self.main_menu = menus.MainMenu()
self.settings_menu = menus.SettingsMenu()
self.settings = Settings()
self.settings.load_settings()
self.settings.write_settings()
self.settings_menu.update_values(self.settings)
def new_game(self) -> None:
"""
Create a new game on the screen.
"""
# TODO generate a new map procedurally
self.map = Map.load("resources/example_map_2.txt")
self.player = Player()
self.map.add_entity(self.player)
self.player.move(self.map.start_y, self.map.start_x)
self.map.spawn_random_entities(randint(3, 10))
def run(self, screen: Any) -> None:
"""
Main infinite loop.
We wait for a player action, then we do what that should be done
when the given key got pressed.
"""
while True: # pragma no cover
screen.clear()
screen.refresh()
self.display_actions(DisplayActions.REFRESH)
key = screen.getkey()
self.handle_key_pressed(
KeyValues.translate_key(key, self.settings), key)
def handle_key_pressed(self, key: Optional[KeyValues], raw_key: str = '')\
-> None:
"""
Indicates what should be done when the given key is pressed,
according to the current game state.
"""
if self.state == GameMode.PLAY:
self.handle_key_pressed_play(key)
elif self.state == GameMode.MAINMENU:
self.handle_key_pressed_main_menu(key)
elif self.state == GameMode.SETTINGS:
self.settings_menu.handle_key_pressed(key, raw_key, self)
self.display_actions(DisplayActions.REFRESH)
def handle_key_pressed_play(self, key: KeyValues) -> None:
"""
In play mode, arrows or zqsd should move the main character.
"""
if key == KeyValues.UP:
if self.player.move_up():
self.map.tick()
elif key == KeyValues.DOWN:
if self.player.move_down():
self.map.tick()
elif key == KeyValues.LEFT:
if self.player.move_left():
self.map.tick()
elif key == KeyValues.RIGHT:
if self.player.move_right():
self.map.tick()
elif key == KeyValues.SPACE:
self.state = GameMode.MAINMENU
def handle_key_pressed_main_menu(self, key: KeyValues) -> None:
"""
In the main menu, we can navigate through options.
"""
if key == KeyValues.DOWN:
self.main_menu.go_down()
if key == KeyValues.UP:
self.main_menu.go_up()
if key == KeyValues.ENTER:
option = self.main_menu.validate()
if option == menus.MainMenuValues.START:
self.state = GameMode.PLAY
elif option == menus.MainMenuValues.SAVE:
self.save_game()
elif option == menus.MainMenuValues.LOAD:
self.load_game()
elif option == menus.MainMenuValues.SETTINGS:
self.state = GameMode.SETTINGS
elif option == menus.MainMenuValues.EXIT:
sys.exit(0)
def game_to_str(self) -> str:
d = dict()
d["Map"] = game.map
d["Player"] = game.player
def save_state(self) -> dict():
return self.map.save_state()
def load_state(self, d: dict) -> None:
self.map.load_state(d)
def load_game(self) -> None:
"""
Loads the game from a file
"""
if os.path.isfile("save.json"):
with open("save.json", "r") as f:
self.load_state(json.loads(f.read()))
def save_game(self) -> None:
"""
Save the game to a file
"""
with open("save.json", "w") as f:
f.write(json.dumps(self.save_state()))