1
0
python-roguelike/setup_game.py

121 lines
3.4 KiB
Python
Raw Normal View History

2022-01-18 14:37:48 -05:00
"""Handle the loading and initialization of game sessions."""
from __future__ import annotations
import copy
import lzma
import pickle
import traceback
from typing import Optional
import tcod
import color
from engine import Engine
import entity_factories
from game_map import GameWorld
2022-01-18 14:37:48 -05:00
import input_handlers
# Load the background image and remove the alpha channel.
background_image = tcod.image.load("menu_background.png")[:, :, :3]
def new_game() -> Engine:
"""Return a brand new game session as an Engine instance."""
map_width = 80
map_height = 43
room_max_size = 10
room_min_size = 6
max_rooms = 30
max_monsters_per_room = 2
max_items_per_room = 2
player = copy.deepcopy(entity_factories.player)
engine = Engine(player)
engine.game_world = GameWorld(
engine=engine,
2022-01-18 14:37:48 -05:00
max_rooms=max_rooms,
room_min_size=room_min_size,
room_max_size=room_max_size,
map_width=map_width,
map_height=map_height,
max_monsters_per_room=max_monsters_per_room,
max_items_per_room=max_items_per_room,
)
engine.game_world.generate_floor()
2022-01-18 14:37:48 -05:00
engine.update_fov()
engine.message_log.add_message(
"Hello and welcome, adventurer, to yet another dungeon!",
color.welcome_text
)
return engine
def load_game(filename: str) -> Engine:
"""Load an engine instance from a file."""
with open(filename, "rb") as f:
engine = pickle.loads(lzma.decompress(f.read()))
assert isinstance(engine, Engine)
return engine
class MainMenu(input_handlers.BaseEventHandler):
"""Handle the main menu rendering and input."""
def on_render(self, console: tcod.Console) -> None:
"""Render the main menu on a background image."""
console.draw_semigraphics(background_image, 0, 0)
console.print(
console.width // 2,
console.height // 2 - 4,
"TOMBS OF THE ANCIENT KINGS",
fg=color.menu_title,
alignment=tcod.CENTER,
)
console.print(
console.width // 2,
console.height - 2,
"By Timothy J. Warren",
fg=color.menu_title,
alignment=tcod.CENTER,
)
menu_width = 24
for i, text in enumerate([
"[N] Play a new game",
"[C] Continue last game",
"[Q] Quit"
]):
console.print(
console.width // 2,
console.height // 2 - 2 + i,
text.ljust(menu_width),
fg=color.menu_text,
bg=color.black,
alignment=tcod.CENTER,
bg_blend=tcod.BKGND_ALPHA(64),
)
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[input_handlers.BaseEventHandler]:
if event.sym in (tcod.event.K_q, tcod.event.K_ESCAPE):
raise SystemExit()
elif event.sym == tcod.event.K_c:
try:
return input_handlers.MainGameEventHandler(load_game("savegame.sav"))
except FileNotFoundError:
return input_handlers.PopupMessage(self, "No saved game to load.")
except Exception as exc:
traceback.print_exc() # Print to stderr.
return input_handlers.PopupMessage(self, f"Failed to load save:\n{exc}")
elif event.sym == tcod.event.K_n:
return input_handlers.MainGameEventHandler(new_game())
return None