Merge branch 'game' into 'master'

Menus

See merge request ynerant/dungeon-battle!7
This commit is contained in:
ynerant 2020-11-06 19:15:29 +01:00
commit bee475c0dd
8 changed files with 249 additions and 30 deletions

View File

@ -1,45 +1,94 @@
import sys
from typing import Any from typing import Any
from .entities.player import Player from .entities.player import Player
from .interfaces import Map from .interfaces import Map
from .mapdisplay import MapDisplay from .mapdisplay import MapDisplay
from .settings import Settings from .settings import Settings
from .term_manager import TermManager 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()
class Game: class Game:
INSTANCE = None def __init__(self) -> None:
self.state = GameMode.MAINMENU
def init(self) -> None: self.main_menu = menus.MainMenu()
Game.INSTANCE = self
self.settings = Settings() self.settings = Settings()
self.settings.load_settings() self.settings.load_settings()
self.settings.write_settings() self.settings.write_settings()
with TermManager() as term_manager:
self._start_game(term_manager.screen)
def _start_game(self, screen: Any) -> None: def new_game(self, init_pad: bool = True) -> None:
# TODO Generate map, or make the possibility to load another one # TODO generate a new map procedurally
m = Map.load("example_map.txt") self.m = Map.load("example_map.txt")
player = Player() self.player = Player()
self.player = player self.player.move(1, 6)
m.add_entity(player) self.m.add_entity(self.player)
player.move(1, 6) self.d = MapDisplay(self.m, self.player, init_pad)
d = MapDisplay(m, player)
@staticmethod
def load_game(filename: str) -> None:
# TODO loading map from a file
raise NotImplementedError()
def run(self, screen: Any) -> None:
while True: while True:
screen.clear() screen.clear()
screen.refresh() screen.refresh()
d.display(player.y, player.y) self.d.display(self.player.y, self.player.x)
key = screen.getkey() key = screen.getkey()
self.handle_key_pressed(key) self.handle_key_pressed(self.translate_key(key))
def handle_key_pressed(self, key: str) -> None: def translate_key(self, key: str) -> KeyValues:
# TODO load keys from settings if key in (self.settings.KEY_DOWN_SECONDARY,
if key == 'z' or key == 'KEY_UP': 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
def handle_key_pressed(self, key: KeyValues) -> None:
if self.state == GameMode.PLAY:
if key == KeyValues.UP:
self.player.move_up() self.player.move_up()
if key == 's' or key == 'KEY_DOWN': if key == KeyValues.DOWN:
self.player.move_down() self.player.move_down()
if key == 'q' or key == 'KEY_LEFT': if key == KeyValues.LEFT:
self.player.move_left() self.player.move_left()
if key == 'd' or key == 'KEY_RIGHT': if key == KeyValues.RIGHT:
self.player.move_right() self.player.move_right()
if self.state == GameMode.MAINMENU:
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)

View File

@ -6,10 +6,11 @@ from dungeonbattle.interfaces import Map
class MapDisplay: class MapDisplay:
def __init__(self, m: Map, player: Player): def __init__(self, m: Map, player: Player, init_pad: bool = True):
self.map = m self.map = m
self.pad = curses.newpad(m.height, m.width + 1)
self.player = player self.player = player
if init_pad:
self.pad = curses.newpad(m.height, m.width + 1)
def update_pad(self) -> None: def update_pad(self) -> None:
self.pad.addstr(0, 0, self.map.draw_string()) self.pad.addstr(0, 0, self.map.draw_string())

34
dungeonbattle/menus.py Normal file
View File

@ -0,0 +1,34 @@
from enum import Enum, auto
from typing import Any
class Menu:
values: list
def __init__(self):
self.position = 0
def go_up(self) -> None:
self.position = max(0, self.position - 1)
def go_down(self) -> None:
self.position = min(len(self.values) - 1, self.position + 1)
def validate(self) -> Any:
return self.values[self.position]
class MainMenuValues(Enum):
START = auto()
SETTINGS = auto()
EXIT = auto()
class MainMenu(Menu):
values = [e for e in MainMenuValues]
class ArbitraryMenu(Menu):
def __init__(self, values: list):
super().__init__()
self.values = values

View File

@ -27,6 +27,8 @@ class Settings:
['d', 'Touche principale pour aller vers la droite'] ['d', 'Touche principale pour aller vers la droite']
self.KEY_RIGHT_SECONDARY = \ self.KEY_RIGHT_SECONDARY = \
['KEY_RIGHT', 'Touche secondaire pour aller vers la droite'] ['KEY_RIGHT', 'Touche secondaire pour aller vers la droite']
self.KEY_ENTER = \
['\n', 'Touche pour valider un menu']
self.TEXTURE_PACK = ['ASCII', 'Pack de textures utilisé'] self.TEXTURE_PACK = ['ASCII', 'Pack de textures utilisé']
def __getattribute__(self, item: str) -> Any: def __getattribute__(self, item: str) -> Any:

View File

@ -0,0 +1,97 @@
import unittest
from dungeonbattle.game import Game, KeyValues, GameMode
from dungeonbattle.menus import MainMenuValues
class TestGame(unittest.TestCase):
def setUp(self) -> None:
"""
Setup game.
"""
self.game = Game()
self.game.new_game(False)
def test_load_game(self) -> None:
self.assertRaises(NotImplementedError, Game.load_game, "game.save")
def test_key_translation(self) -> None:
"""
Test key bindings.
"""
self.assertEqual(self.game.translate_key(
self.game.settings.KEY_UP_PRIMARY), KeyValues.UP)
self.assertEqual(self.game.translate_key(
self.game.settings.KEY_UP_SECONDARY), KeyValues.UP)
self.assertEqual(self.game.translate_key(
self.game.settings.KEY_DOWN_PRIMARY), KeyValues.DOWN)
self.assertEqual(self.game.translate_key(
self.game.settings.KEY_DOWN_SECONDARY), KeyValues.DOWN)
self.assertEqual(self.game.translate_key(
self.game.settings.KEY_LEFT_PRIMARY), KeyValues.LEFT)
self.assertEqual(self.game.translate_key(
self.game.settings.KEY_LEFT_SECONDARY), KeyValues.LEFT)
self.assertEqual(self.game.translate_key(
self.game.settings.KEY_RIGHT_PRIMARY), KeyValues.RIGHT)
self.assertEqual(self.game.translate_key(
self.game.settings.KEY_RIGHT_SECONDARY), KeyValues.RIGHT)
self.assertEqual(self.game.translate_key(
self.game.settings.KEY_ENTER), KeyValues.ENTER)
def test_key_press(self) -> None:
"""
Press a key and see what is done.
"""
self.assertEqual(self.game.state, GameMode.MAINMENU)
self.assertEqual(self.game.main_menu.validate(),
MainMenuValues.START)
self.game.handle_key_pressed(KeyValues.UP)
self.assertEqual(self.game.main_menu.validate(),
MainMenuValues.START)
self.game.handle_key_pressed(KeyValues.DOWN)
self.assertEqual(self.game.main_menu.validate(),
MainMenuValues.SETTINGS)
self.game.handle_key_pressed(KeyValues.ENTER)
self.assertEqual(self.game.state, GameMode.SETTINGS)
self.game.state = GameMode.MAINMENU
self.game.handle_key_pressed(KeyValues.DOWN)
self.assertEqual(self.game.main_menu.validate(),
MainMenuValues.EXIT)
self.assertRaises(SystemExit, self.game.handle_key_pressed,
KeyValues.ENTER)
self.game.handle_key_pressed(KeyValues.UP)
self.assertEqual(self.game.main_menu.validate(),
MainMenuValues.SETTINGS)
self.game.handle_key_pressed(KeyValues.UP)
self.assertEqual(self.game.main_menu.validate(),
MainMenuValues.START)
self.game.handle_key_pressed(KeyValues.ENTER)
self.assertEqual(self.game.state, GameMode.PLAY)
y, x = self.game.player.y, self.game.player.x
self.game.handle_key_pressed(KeyValues.DOWN)
new_y, new_x = self.game.player.y, self.game.player.x
self.assertEqual(new_y, y + 1)
self.assertEqual(new_x, x)
y, x = new_y, new_x
self.game.handle_key_pressed(KeyValues.RIGHT)
new_y, new_x = self.game.player.y, self.game.player.x
self.assertEqual(new_y, y)
self.assertEqual(new_x, x + 1)
y, x = self.game.player.y, self.game.player.x
self.game.handle_key_pressed(KeyValues.UP)
new_y, new_x = self.game.player.y, self.game.player.x
self.assertEqual(new_y, y - 1)
self.assertEqual(new_x, x)
y, x = self.game.player.y, self.game.player.x
self.game.handle_key_pressed(KeyValues.LEFT)
new_y, new_x = self.game.player.y, self.game.player.x
self.assertEqual(new_y, y)
self.assertEqual(new_x, x - 1)

View File

@ -0,0 +1,24 @@
import unittest
from dungeonbattle.menus import ArbitraryMenu, MainMenu, MainMenuValues
class TestMenus(unittest.TestCase):
def test_scroll_menu(self) -> None:
"""
Test to scroll the menu.
"""
arbitrary_menu = ArbitraryMenu([])
self.assertEqual(arbitrary_menu.position, 0)
main_menu = MainMenu()
self.assertEqual(main_menu.position, 0)
self.assertEqual(main_menu.validate(), MainMenuValues.START)
main_menu.go_up()
self.assertEqual(main_menu.validate(), MainMenuValues.START)
main_menu.go_down()
self.assertEqual(main_menu.validate(), MainMenuValues.SETTINGS)
main_menu.go_down()
self.assertEqual(main_menu.validate(), MainMenuValues.EXIT)
main_menu.go_down()
self.assertEqual(main_menu.validate(), MainMenuValues.EXIT)

View File

@ -0,0 +1,8 @@
# This is the base ascii texturepack
ascii = {
"EMPTY": ' ',
"WALL": '#',
"FLOOR": '.',
"PLAYER": '@'
}

View File

@ -1,5 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
from dungeonbattle.game import Game from dungeonbattle.game import Game
from dungeonbattle.term_manager import TermManager
if __name__ == "__main__": if __name__ == "__main__":
Game().init() with TermManager() as term_manager:
game = Game()
game.new_game()
game.run(term_manager.screen)