import sys from typing import Any from .display.display import Display from .display.mapdisplay import MapDisplay from .display.menudisplay import MenuDisplay from .display.texturepack import TexturePack from .entities.player import Player from .interfaces import Map from .settings import Settings from enum import Enum, auto from . import menus class GameMode(Enum): MAINMENU = auto() PLAY = auto() SETTINGS = auto() INVENTORY = auto() class KeyValues(Enum): UP = auto() DOWN = auto() LEFT = auto() RIGHT = auto() ENTER = auto() SPACE = auto() class Game: map: Map player: Player menu_display: MenuDisplay map_display: MapDisplay display: Display def __init__(self) -> None: """ Init the game. """ self.state = GameMode.MAINMENU self.main_menu = menus.MainMenu() self.settings = Settings() self.settings.load_settings() self.settings.write_settings() def new_game(self, screen: Any) -> None: """ Create a new game on the screen. """ # TODO generate a new map procedurally self.map = Map.load("example_map.txt") self.map.currenty = 1 self.map.currentx = 6 self.player = Player() self.player.move(1, 6) self.map.add_entity(self.player) self.display = Display(screen, self.map, TexturePack.get_pack(self.settings.TEXTURE_PACK)) # self.menu_display = MenuDisplay(screen, self.main_menu, 0, 0) @staticmethod def load_game(filename: str) -> None: # TODO loading map from a file raise NotImplementedError() 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: screen.clear() screen.refresh() self.display.refresh(self.map, self.player) key = screen.getkey() self.handle_key_pressed(self.translate_key(key)) def translate_key(self, key: str) -> KeyValues: """ Translate the raw string key into an enum value that we can use. """ if key in (self.settings.KEY_DOWN_SECONDARY, self.settings.KEY_DOWN_PRIMARY): return KeyValues.DOWN elif key in (self.settings.KEY_LEFT_PRIMARY, self.settings.KEY_LEFT_SECONDARY): return KeyValues.LEFT elif key in (self.settings.KEY_RIGHT_PRIMARY, self.settings.KEY_RIGHT_SECONDARY): return KeyValues.RIGHT elif key in (self.settings.KEY_UP_PRIMARY, self.settings.KEY_UP_SECONDARY): return KeyValues.UP elif key == self.settings.KEY_ENTER: return KeyValues.ENTER elif key == ' ': return KeyValues.SPACE def handle_key_pressed(self, key: KeyValues) -> 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.handle_key_pressed_settings(key) self.display.refresh(self.map, self.player) def handle_key_pressed_play(self, key: KeyValues) -> None: """ In play mode, arrows or zqsd should move the main character. """ if key == KeyValues.UP: self.player.move_up() elif key == KeyValues.DOWN: self.player.move_down() elif key == KeyValues.LEFT: self.player.move_left() elif key == KeyValues.RIGHT: self.player.move_right() elif key == KeyValues.SPACE: self.state = GameMode.MAINMENU self.display = self.menu_display 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 self.display = self.map_display elif option == menus.MainMenuValues.SETTINGS: self.state = GameMode.SETTINGS elif option == menus.MainMenuValues.EXIT: sys.exit(0) def handle_key_pressed_settings(self, key: KeyValues) -> None: """ For now, in the settings mode, we can only go backwards. """ if key == KeyValues.SPACE: self.state = GameMode.MAINMENU self.display = self.menu_display