147 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import sys
 | |
| from typing import Any
 | |
| 
 | |
| from .display.display import Display
 | |
| from .entities.player import Player
 | |
| from .interfaces import Map
 | |
| from .settings import Settings
 | |
| from enum import Enum, auto
 | |
| from . import menus
 | |
| from typing import Callable
 | |
| 
 | |
| 
 | |
| 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
 | |
|     display_refresh: Callable[[], None]
 | |
| 
 | |
|     def __init__(self) -> None:
 | |
|         """
 | |
|         Init the game.
 | |
|         """
 | |
|         self.state = GameMode.PLAY
 | |
|         self.main_menu = menus.MainMenu()
 | |
|         self.settings = Settings()
 | |
|         self.settings.load_settings()
 | |
|         self.settings.write_settings()
 | |
| 
 | |
|     def new_game(self) -> 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)
 | |
| 
 | |
|     @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()
 | |
|             key = screen.getkey()
 | |
|             self.handle_key_pressed(self.translate_key(key))
 | |
|             self.display_refresh()
 | |
| 
 | |
|     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()
 | |
| 
 | |
|     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
 | |
| 
 | |
|     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.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
 |