squirrel-battle/dungeonbattle/game.py

155 lines
4.9 KiB
Python
Raw Normal View History

2020-11-06 17:11:59 +00:00
import sys
2020-11-06 14:33:26 +00:00
from typing import Any
2020-11-08 22:26:54 +00:00
from .display.display import Display
2020-11-08 22:08:38 +00:00
from .display.mapdisplay import MapDisplay
2020-11-08 21:59:11 +00:00
from .display.menudisplay import MenuDisplay
2020-11-08 22:08:38 +00:00
from .display.texturepack import TexturePack
from .entities.player import Player
2020-10-23 12:53:08 +00:00
from .interfaces import Map
from .settings import Settings
2020-11-06 16:24:20 +00:00
from enum import Enum, auto
2020-11-06 17:06:28 +00:00
from . import menus
2020-11-06 16:24:20 +00:00
2020-11-06 17:11:59 +00:00
2020-11-06 16:24:20 +00:00
class GameMode(Enum):
MAINMENU = auto()
PLAY = auto()
SETTINGS = auto()
INVENTORY = auto()
class KeyValues(Enum):
UP = auto()
DOWN = auto()
LEFT = auto()
RIGHT = auto()
ENTER = auto()
2020-11-08 22:26:54 +00:00
SPACE = auto()
2020-10-23 12:53:08 +00:00
class Game:
2020-11-08 22:26:54 +00:00
map: Map
player: Player
menu_display: MenuDisplay
map_display: MapDisplay
2020-11-09 00:33:23 +00:00
display: Display
2020-11-08 22:26:54 +00:00
2020-11-06 17:39:55 +00:00
def __init__(self) -> None:
2020-11-08 22:31:17 +00:00
"""
Init the game.
"""
2020-11-06 16:24:20 +00:00
self.state = GameMode.MAINMENU
2020-11-06 17:06:28 +00:00
self.main_menu = menus.MainMenu()
self.settings = Settings()
self.settings.load_settings()
self.settings.write_settings()
2020-10-23 12:53:08 +00:00
2020-11-06 19:24:19 +00:00
def new_game(self, screen: Any) -> None:
2020-11-08 22:31:17 +00:00
"""
Create a new game on the screen.
"""
2020-10-23 16:01:39 +00:00
# TODO generate a new map procedurally
2020-11-08 22:26:54 +00:00
self.map = Map.load("example_map.txt")
2020-11-10 09:49:11 +00:00
self.map.currenty = 1
self.map.currentx = 6
2020-10-23 16:01:39 +00:00
self.player = Player()
2020-11-06 17:38:10 +00:00
self.player.move(1, 6)
2020-11-08 22:26:54 +00:00
self.map.add_entity(self.player)
2020-11-10 09:49:11 +00:00
self.display = Display(screen, self.map, TexturePack.get_pack(self.settings.TEXTURE_PACK))
2020-11-09 00:33:23 +00:00
# self.menu_display = MenuDisplay(screen, self.main_menu, 0, 0)
2020-10-23 16:01:39 +00:00
2020-11-06 17:06:28 +00:00
@staticmethod
2020-11-06 17:11:59 +00:00
def load_game(filename: str) -> None:
2020-10-23 16:01:39 +00:00
# TODO loading map from a file
raise NotImplementedError()
2020-11-06 17:11:59 +00:00
def run(self, screen: Any) -> None:
2020-11-08 22:31:17 +00:00
"""
Main infinite loop.
We wait for a player action, then we do what that should be done
when the given key got pressed.
"""
2020-10-23 12:53:08 +00:00
while True:
2020-10-23 13:40:32 +00:00
screen.clear()
2020-10-23 12:53:08 +00:00
screen.refresh()
2020-11-10 09:49:11 +00:00
self.display.refresh(self.map, self.player)
2020-10-23 12:53:08 +00:00
key = screen.getkey()
2020-11-06 16:24:20 +00:00
self.handle_key_pressed(self.translate_key(key))
2020-11-06 17:11:59 +00:00
def translate_key(self, key: str) -> KeyValues:
2020-11-08 22:31:17 +00:00
"""
Translate the raw string key into an enum value that we can use.
"""
2020-11-06 17:11:59 +00:00
if key in (self.settings.KEY_DOWN_SECONDARY,
self.settings.KEY_DOWN_PRIMARY):
2020-11-06 16:24:20 +00:00
return KeyValues.DOWN
2020-11-06 17:11:59 +00:00
elif key in (self.settings.KEY_LEFT_PRIMARY,
self.settings.KEY_LEFT_SECONDARY):
2020-11-06 16:24:20 +00:00
return KeyValues.LEFT
2020-11-06 17:11:59 +00:00
elif key in (self.settings.KEY_RIGHT_PRIMARY,
self.settings.KEY_RIGHT_SECONDARY):
2020-11-06 16:24:20 +00:00
return KeyValues.RIGHT
2020-11-06 17:11:59 +00:00
elif key in (self.settings.KEY_UP_PRIMARY,
self.settings.KEY_UP_SECONDARY):
2020-11-06 16:24:20 +00:00
return KeyValues.UP
2020-11-06 17:25:02 +00:00
elif key == self.settings.KEY_ENTER:
return KeyValues.ENTER
2020-11-08 22:26:54 +00:00
elif key == ' ':
return KeyValues.SPACE
2020-11-06 16:24:20 +00:00
def handle_key_pressed(self, key: KeyValues) -> None:
2020-11-08 22:31:17 +00:00
"""
Indicates what should be done when the given key is pressed,
according to the current game state.
"""
2020-11-06 17:06:28 +00:00
if self.state == GameMode.PLAY:
2020-11-08 22:26:54 +00:00
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)
2020-11-08 22:26:54 +00:00
def handle_key_pressed_play(self, key: KeyValues) -> None:
2020-11-08 22:31:17 +00:00
"""
In play mode, arrows or zqsd should move the main character.
"""
2020-11-08 22:26:54 +00:00
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
2020-11-09 00:33:23 +00:00
self.display = self.menu_display
2020-11-08 22:26:54 +00:00
def handle_key_pressed_main_menu(self, key: KeyValues) -> None:
2020-11-08 22:31:17 +00:00
"""
In the main menu, we can navigate through options.
"""
2020-11-08 22:26:54 +00:00
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
2020-11-09 00:33:23 +00:00
self.display = self.map_display
2020-11-08 22:26:54 +00:00
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:
2020-11-08 22:31:17 +00:00
"""
For now, in the settings mode, we can only go backwards.
"""
2020-11-08 22:26:54 +00:00
if key == KeyValues.SPACE:
self.state = GameMode.MAINMENU
2020-11-09 00:33:23 +00:00
self.display = self.menu_display