Restructure event handling
Events start in the Interface. The interface gets first crack at any incoming events. If the interface doesn't handle the event, it is given to the engine. The engine has an EngineEventHandler that yields actions just like the event handler prior to this change. The interface's event handler passes events to each window in the interface. Windows can choose to handle events however they like, and they return a bool indicating whether the event was fully handled.
This commit is contained in:
parent
ee1c6f2222
commit
003aedf30e
6 changed files with 197 additions and 116 deletions
|
|
@ -1,65 +1,26 @@
|
|||
# Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
'''Defines event handling mechanisms.'''
|
||||
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
import tcod
|
||||
import tcod.event as tev
|
||||
|
||||
from . import log
|
||||
from .actions.action import Action
|
||||
from .actions.game import ExitAction, RegenerateRoomsAction, BumpAction, WaitAction
|
||||
from .geometry import Direction, Point
|
||||
from .actions.game import BumpAction, ExitAction, RegenerateRoomsAction, WaitAction
|
||||
from .geometry import Direction
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .engine import Engine
|
||||
|
||||
|
||||
class EventHandler(tcod.event.EventDispatch[Action]):
|
||||
'''Abstract event handler class'''
|
||||
class EngineEventHandler(tev.EventDispatch[Action]):
|
||||
'''Handles event on behalf of the game engine, dispatching Actions back to the engine.'''
|
||||
|
||||
def __init__(self, engine: 'Engine'):
|
||||
super().__init__()
|
||||
self.engine = engine
|
||||
|
||||
def handle_events(self, context: tcod.context.Context):
|
||||
'''Wait for events and handle them.'''
|
||||
for event in tcod.event.wait():
|
||||
context.convert_event(event)
|
||||
self.handle_event(event)
|
||||
|
||||
def handle_event(self, event: tcod.event.Event):
|
||||
'''
|
||||
Handle an event by transforming it into an Action and processing it until it is completed. If the Action
|
||||
succeeds, also process actions from other Entities.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
event : tcod.event.Event
|
||||
The event to handle
|
||||
'''
|
||||
action = self.dispatch(event)
|
||||
|
||||
# Unhandled event. Ignore it.
|
||||
if not action:
|
||||
log.EVENTS.debug('Unhandled event: %s', event)
|
||||
return
|
||||
|
||||
self.engine.process_input_action(action)
|
||||
|
||||
def ev_quit(self, event: tcod.event.Quit) -> Optional[Action]:
|
||||
return ExitAction()
|
||||
|
||||
|
||||
class MainGameEventHandler(EventHandler):
|
||||
'''
|
||||
Handler of `tcod` events for the main game.
|
||||
|
||||
Receives input from the player and dispatches actions to the game engine to interat with the hero and other objects
|
||||
in the game.
|
||||
'''
|
||||
|
||||
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]:
|
||||
def ev_keydown(self, event: tev.KeyDown) -> Optional[Action]:
|
||||
action: Optional[Action] = None
|
||||
|
||||
hero = self.engine.hero
|
||||
|
|
@ -84,8 +45,6 @@ class MainGameEventHandler(EventHandler):
|
|||
action = BumpAction(hero, Direction.NorthEast)
|
||||
case tcod.event.KeySym.y:
|
||||
action = BumpAction(hero, Direction.NorthWest)
|
||||
case tcod.event.KeySym.ESCAPE:
|
||||
action = ExitAction()
|
||||
case tcod.event.KeySym.SPACE:
|
||||
action = RegenerateRoomsAction()
|
||||
case tcod.event.KeySym.PERIOD:
|
||||
|
|
@ -94,22 +53,16 @@ class MainGameEventHandler(EventHandler):
|
|||
|
||||
return action
|
||||
|
||||
def ev_mousemotion(self, event: tcod.event.MouseMotion) -> Optional[Action]:
|
||||
mouse_point = Point(event.tile.x, event.tile.y)
|
||||
if not self.engine.map.tile_is_in_bounds(mouse_point):
|
||||
mouse_point = None
|
||||
self.engine.update_mouse_point(mouse_point)
|
||||
def ev_quit(self, event: tcod.event.Quit) -> Optional[Action]:
|
||||
return ExitAction()
|
||||
|
||||
|
||||
class GameOverEventHandler(EventHandler):
|
||||
class GameOverEventHandler(tev.EventDispatch[Action]):
|
||||
'''When the game is over (the hero dies, the player quits, etc), this event handler takes over.'''
|
||||
|
||||
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]:
|
||||
action: Optional[Action] = None
|
||||
def __init__(self, engine: 'Engine'):
|
||||
super().__init__()
|
||||
self.engine = engine
|
||||
|
||||
sym = event.sym
|
||||
match sym:
|
||||
case tcod.event.KeySym.ESCAPE:
|
||||
action = ExitAction()
|
||||
|
||||
return action
|
||||
def ev_quit(self, event: tev.Quit) -> Optional[Action]:
|
||||
return ExitAction()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue