-
Notifications
You must be signed in to change notification settings - Fork 0
/
engine.py
127 lines (91 loc) · 3.72 KB
/
engine.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
from tcod.context import Context
from tcod.console import Console
from tcod.map import compute_fov
import tcod
from typing import Set, Iterable, Any
from game_map import GameMap
from player import Player
from screen_handlers import MainGameScreenHandler, ViewInventoryScreenHandler, DropScreenHandler
from message_log import MessageLog
MENU_TYPES = {
'inventory': ViewInventoryScreenHandler,
'drop': DropScreenHandler,
}
class Engine:
def __init__(self, *,
screen_handler: MainGameScreenHandler,
game_map: GameMap,
player: Player,
message_log: MessageLog,
context: Context,
map_width: int,
map_height: int
):
self.game_map = game_map
self.player = player
self.message_log = message_log
# Screen handlers render certain parts of the screen,
# and also determine what user input does based on the
# current screen.
self.main_screen_handler = screen_handler
self.screen_handler_list = [screen_handler]
self.active_screen_handler = screen_handler
self.context = context
self.update_fov()
self.map_width = map_width
self.map_height = map_height
def handle_events(self, events: Iterable[Any]) -> None:
turn_code = 0
self.active_screen_handler = self.screen_handler_list[-1]
for event in events:
new_code = self.active_screen_handler.handle_event(event, self)
if new_code > turn_code:
turn_code = new_code
return turn_code
def add_menu(self, menu_type):
try:
screen_handler = MENU_TYPES[menu_type](self)
self.screen_handler_list.append(screen_handler)
self.active_screen_handler = screen_handler
except KeyError:
self.message_log.log("Error: Cannot open menu", color=(255,0,0))
def delete_current_screen_handler(self):
del self.screen_handler_list[-1]
def creatures_act(self):
for creature in self.game_map.creatures:
action = creature.act(self)
action.perform(self, creature, self.message_log)
def render(self, console: Console) -> None:
for screen_handler in self.screen_handler_list:
screen_handler.on_render(console, self)
def update_fov(self) -> None:
"""Recompute the visible area based on the players point of view."""
self.game_map.visible[:] = compute_fov(
self.game_map.tiles["transparent"],
(self.player.x, self.player.y),
radius=6,
)
# If a tile is "visible" it should be added to "explored".
self.game_map.explored |= self.game_map.visible
def main_loop(self, console):
while True:
self.context.present(console)
console.clear()
turn_code = 0
while not turn_code > 0:
events = tcod.event.wait()
turn_code = self.handle_events(events)
if turn_code > 0:
if turn_code > 1:
new_creatures = []
for creature in self.game_map.creatures:
if not creature.is_dead():
new_creatures.append(creature)
else:
self.message_log.log(f"You defeated the {creature.name}!")
self.game_map.creatures = new_creatures
self.creatures_act()
if self.player.is_dead():
print("Game over!")
break
self.render(console)