Added functionnal save system and broken load system
This commit is contained in:
parent
eca6b9af1f
commit
f67eae3803
Binary file not shown.
Binary file not shown.
|
@ -5,6 +5,9 @@ from ..interfaces import FightingEntity, Map
|
||||||
|
|
||||||
|
|
||||||
class Monster(FightingEntity):
|
class Monster(FightingEntity):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
def act(self, m: Map) -> None:
|
def act(self, m: Map) -> None:
|
||||||
"""
|
"""
|
||||||
By default, a monster will move randomly where it is possible
|
By default, a monster will move randomly where it is possible
|
||||||
|
@ -35,24 +38,32 @@ class Monster(FightingEntity):
|
||||||
|
|
||||||
|
|
||||||
class Beaver(Monster):
|
class Beaver(Monster):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
name = "beaver"
|
name = "beaver"
|
||||||
maxhealth = 30
|
maxhealth = 30
|
||||||
strength = 2
|
strength = 2
|
||||||
|
|
||||||
|
|
||||||
class Hedgehog(Monster):
|
class Hedgehog(Monster):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
name = "hedgehog"
|
name = "hedgehog"
|
||||||
maxhealth = 10
|
maxhealth = 10
|
||||||
strength = 3
|
strength = 3
|
||||||
|
|
||||||
|
|
||||||
class Rabbit(Monster):
|
class Rabbit(Monster):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
name = "rabbit"
|
name = "rabbit"
|
||||||
maxhealth = 15
|
maxhealth = 15
|
||||||
strength = 1
|
strength = 1
|
||||||
|
|
||||||
|
|
||||||
class TeddyBear(Monster):
|
class TeddyBear(Monster):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
name = "teddy_bear"
|
name = "teddy_bear"
|
||||||
maxhealth = 50
|
maxhealth = 50
|
||||||
strength = 0
|
strength = 0
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
from random import randint
|
from random import randint
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional,Generator
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
from .entities.player import Player
|
from .entities.player import Player
|
||||||
from .enums import GameMode, KeyValues, DisplayActions
|
from .enums import GameMode, KeyValues, DisplayActions
|
||||||
|
@ -37,11 +39,6 @@ class Game:
|
||||||
self.player.move(self.map.start_y, self.map.start_x)
|
self.player.move(self.map.start_y, self.map.start_x)
|
||||||
self.map.spawn_random_entities(randint(3, 10))
|
self.map.spawn_random_entities(randint(3, 10))
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def load_game(filename: str) -> None:
|
|
||||||
# TODO loading map from a file
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def run(self, screen: Any) -> None:
|
def run(self, screen: Any) -> None:
|
||||||
"""
|
"""
|
||||||
Main infinite loop.
|
Main infinite loop.
|
||||||
|
@ -65,7 +62,7 @@ class Game:
|
||||||
if self.state == GameMode.PLAY:
|
if self.state == GameMode.PLAY:
|
||||||
self.handle_key_pressed_play(key)
|
self.handle_key_pressed_play(key)
|
||||||
elif self.state == GameMode.MAINMENU:
|
elif self.state == GameMode.MAINMENU:
|
||||||
self.main_menu.handle_key_pressed(key, self)
|
self.handle_key_pressed_main_menu(key)
|
||||||
elif self.state == GameMode.SETTINGS:
|
elif self.state == GameMode.SETTINGS:
|
||||||
self.settings_menu.handle_key_pressed(key, raw_key, self)
|
self.settings_menu.handle_key_pressed(key, raw_key, self)
|
||||||
self.display_actions(DisplayActions.REFRESH)
|
self.display_actions(DisplayActions.REFRESH)
|
||||||
|
@ -88,3 +85,50 @@ class Game:
|
||||||
self.map.tick()
|
self.map.tick()
|
||||||
elif key == KeyValues.SPACE:
|
elif key == KeyValues.SPACE:
|
||||||
self.state = GameMode.MAINMENU
|
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()))
|
||||||
|
|
|
@ -78,6 +78,17 @@ class Map:
|
||||||
|
|
||||||
return Map(width, height, tiles, start_y, start_x)
|
return Map(width, height, tiles, start_y, start_x)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def load_dungeon_from_string(content: str) -> "Map":
|
||||||
|
"""
|
||||||
|
Transforms a string into the list of corresponding tiles
|
||||||
|
"""
|
||||||
|
lines = content.split("\n")
|
||||||
|
lines = [line for line in lines[1:] if line]
|
||||||
|
tiles = [[Tile.from_ascii_char(c)
|
||||||
|
for x, c in enumerate(line)] for y, line in enumerate(lines)]
|
||||||
|
return tiles
|
||||||
|
|
||||||
def draw_string(self, pack: TexturePack) -> str:
|
def draw_string(self, pack: TexturePack) -> str:
|
||||||
"""
|
"""
|
||||||
Draw the current map as a string object that can be rendered
|
Draw the current map as a string object that can be rendered
|
||||||
|
@ -108,14 +119,39 @@ class Map:
|
||||||
for entity in self.entities:
|
for entity in self.entities:
|
||||||
entity.act(self)
|
entity.act(self)
|
||||||
|
|
||||||
|
def save_state(self) -> dict:
|
||||||
|
d = dict()
|
||||||
|
d["width"] = self.width
|
||||||
|
d["height"] = self.height
|
||||||
|
d["start_y"] = self.start_y
|
||||||
|
d["start_x"] = self.start_x
|
||||||
|
d["currentx"] = self.currentx
|
||||||
|
d["currenty"] = self.currenty
|
||||||
|
for enti in self.entities:
|
||||||
|
d.update(enti.save_state())
|
||||||
|
d["map"] = self.draw_string(TexturePack.ASCII_PACK)
|
||||||
|
return d
|
||||||
|
|
||||||
|
def load_state(self, d: dict) -> None:
|
||||||
|
self.width = d["width"]
|
||||||
|
self.height = d["height"]
|
||||||
|
self.start_y = d["start_y"]
|
||||||
|
self.start_x = d["start_x"]
|
||||||
|
self.currentx = d["currentx"]
|
||||||
|
self.currenty = d["currenty"]
|
||||||
|
self.map = self.load_dungeon_from_string(d["map"])
|
||||||
|
#add entities
|
||||||
|
|
||||||
class Tile(Enum):
|
class Tile(Enum):
|
||||||
EMPTY = auto()
|
EMPTY = auto()
|
||||||
WALL = auto()
|
WALL = auto()
|
||||||
FLOOR = auto()
|
FLOOR = auto()
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def from_ascii_char(cls, ch: str) -> "Tile":
|
def from_ascii_char(ch: str) -> "Tile":
|
||||||
|
"""
|
||||||
|
Maps an ascii character to its equivalent in the texture pack
|
||||||
|
"""
|
||||||
for tile in Tile:
|
for tile in Tile:
|
||||||
if tile.char(TexturePack.ASCII_PACK) == ch:
|
if tile.char(TexturePack.ASCII_PACK) == ch:
|
||||||
return tile
|
return tile
|
||||||
|
@ -206,6 +242,22 @@ class Entity:
|
||||||
Rabbit, TeddyBear
|
Rabbit, TeddyBear
|
||||||
return [Beaver, Bomb, Heart, Hedgehog, Rabbit, TeddyBear]
|
return [Beaver, Bomb, Heart, Hedgehog, Rabbit, TeddyBear]
|
||||||
|
|
||||||
|
def save_state(self) -> dict:
|
||||||
|
"""
|
||||||
|
Saves the coordinates of the entity
|
||||||
|
"""
|
||||||
|
d = dict()
|
||||||
|
d["x"] = self.x
|
||||||
|
d["y"] = self.y
|
||||||
|
return d
|
||||||
|
|
||||||
|
def recover_state(self, d : dict) -> None:
|
||||||
|
"""
|
||||||
|
Loads the coordinates of the entity from a dictionnary
|
||||||
|
"""
|
||||||
|
self.x = d["x"]
|
||||||
|
self.y = d["y"]
|
||||||
|
|
||||||
|
|
||||||
class FightingEntity(Entity):
|
class FightingEntity(Entity):
|
||||||
maxhealth: int
|
maxhealth: int
|
||||||
|
@ -222,6 +274,15 @@ class FightingEntity(Entity):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.health = self.maxhealth
|
self.health = self.maxhealth
|
||||||
self.dead = False
|
self.dead = False
|
||||||
|
self.health = 0
|
||||||
|
self.strength = 0
|
||||||
|
self.dead = False
|
||||||
|
self.intelligence = 0
|
||||||
|
self.charisma = 0
|
||||||
|
self.dexterity = 0
|
||||||
|
self.constitution = 0
|
||||||
|
self.level = 1
|
||||||
|
|
||||||
|
|
||||||
def hit(self, opponent: "FightingEntity") -> None:
|
def hit(self, opponent: "FightingEntity") -> None:
|
||||||
opponent.take_damage(self, self.strength)
|
opponent.take_damage(self, self.strength)
|
||||||
|
@ -234,3 +295,17 @@ class FightingEntity(Entity):
|
||||||
def die(self) -> None:
|
def die(self) -> None:
|
||||||
self.dead = True
|
self.dead = True
|
||||||
self.map.remove_entity(self)
|
self.map.remove_entity(self)
|
||||||
|
|
||||||
|
def keys(self) -> list:
|
||||||
|
return ["maxhealth", "health", "level", "dead", "strength", "intelligence", "charisma", "dexterity", "constitution"]
|
||||||
|
|
||||||
|
def save_state(self) -> dict:
|
||||||
|
d = super().save_state()
|
||||||
|
for name in self.keys():
|
||||||
|
d[name] = self.__getattribute__(name)
|
||||||
|
return d
|
||||||
|
|
||||||
|
def recover_state(self, d : dict) -> None:
|
||||||
|
super().recover_state(d)
|
||||||
|
for name in d.keys():
|
||||||
|
self.__setattribute__(name, d[name])
|
||||||
|
|
|
@ -25,6 +25,8 @@ class Menu:
|
||||||
|
|
||||||
class MainMenuValues(Enum):
|
class MainMenuValues(Enum):
|
||||||
START = 'Jouer'
|
START = 'Jouer'
|
||||||
|
SAVE = 'Sauvegarder'
|
||||||
|
LOAD = 'Charger'
|
||||||
SETTINGS = 'Paramètres'
|
SETTINGS = 'Paramètres'
|
||||||
EXIT = 'Quitter'
|
EXIT = 'Quitter'
|
||||||
|
|
||||||
|
@ -35,23 +37,6 @@ class MainMenuValues(Enum):
|
||||||
class MainMenu(Menu):
|
class MainMenu(Menu):
|
||||||
values = [e for e in MainMenuValues]
|
values = [e for e in MainMenuValues]
|
||||||
|
|
||||||
def handle_key_pressed(self, key: KeyValues, game: Any) -> None:
|
|
||||||
"""
|
|
||||||
In the main menu, we can navigate through options.
|
|
||||||
"""
|
|
||||||
if key == KeyValues.DOWN:
|
|
||||||
self.go_down()
|
|
||||||
if key == KeyValues.UP:
|
|
||||||
self.go_up()
|
|
||||||
if key == KeyValues.ENTER:
|
|
||||||
option = self.validate()
|
|
||||||
if option == MainMenuValues.START:
|
|
||||||
game.state = GameMode.PLAY
|
|
||||||
elif option == MainMenuValues.SETTINGS:
|
|
||||||
game.state = GameMode.SETTINGS
|
|
||||||
elif option == MainMenuValues.EXIT:
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
class SettingsMenu(Menu):
|
class SettingsMenu(Menu):
|
||||||
waiting_for_key: bool = False
|
waiting_for_key: bool = False
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
1 1
|
||||||
|
##############################################################################################################
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
#............................................................................................................#
|
||||||
|
##############################################################################################################
|
|
@ -0,0 +1 @@
|
||||||
|
{"width": 80, "height": 40, "start_y": 1, "start_x": 17, "currentx": 29, "currenty": 25, "x": 74, "y": 22, "maxhealth": 50, "health": 0, "level": 1, "dead": false, "strength": 0, "intelligence": 0, "charisma": 0, "dexterity": 0, "constitution": 0, "map": " ########### ######### \n #.........# #.......# \n #.........# ############.......# \n #.........###############..........#.......############## \n #.........#........................#....................# \n #.........#.............#..........#.......#............# \n ########.########.............#..................#............# \n #.........# #.............####.#######.......#............# \n #.........# #.............##.........###################### \n #.........# #####.##########.........# ########### \n #.........# #......# #.........# #.........# \n ########.##########......# #.........# #.........# \n #...........##......# #.........# #.........# \n #...........##......# #.........# #.........# \n #...........##......# #.........# ################.###### \n #...........##......# #.........# #.................############\n #...........##......# ########.########.......#.........#..........#\n #...........##......# #...............#.......#.........#..........#\n #...........######### #...............#.......#.........#..........#\n #...........# #...............#.......#....................#\n #####.####### #.......................#.........#..........#\n #.........# #...............###################..........#\n #.........############ #...............# #..........#\n #.........#..........# #...............# ############\n #....................#####.###########.############# \n ########.#########...................# #.............# \n #........# #..........#........# #.............######### \n #........# ######.##########........# #.............#.......# \n #........# #..........# #........# #.....................# \n #........# #..........# #........# #.............#.......# \n #........# #..........# #........# #.............#.......# \n #........# #..........# #........# #.............#.......# \n #........# #..........#########.##### #.............#.......# \n #........# #..........#.........# ##########.############.####### \n #........# #..........#.........# #..............# #..........# \n ########## #..........#.........# #..............# #..........# \n ############.........# #..............# #..........# \n #.........# #..............# #..........# \n ########### #..............# #..........# \n ################ ############ "}
|
Loading…
Reference in New Issue