1
0
Fork 0

Add cursor mode to look around using keyboard controls

This commit is contained in:
Timothy Warren 2022-01-13 15:37:06 -05:00
parent 5b5f49bf6b
commit bebd9d617e
1 changed files with 71 additions and 0 deletions

View File

@ -56,6 +56,11 @@ WAIT_KEYS = {
tcod.event.K_CLEAR,
}
CONFIRM_KEYS = {
tcod.event.K_RETURN,
tcod.event.K_KP_ENTER,
}
class EventHandler(tcod.event.EventDispatch[Action]):
def __init__(self, engine: Engine):
@ -225,6 +230,70 @@ class InventoryDropHandler(InventoryEventHandler):
return actions.DropItem(self.engine.player, item)
class SelectIndexHandler(AskUserEventHandler):
"""Handles asking the user for an index on the map."""
def __init__(self, engine: Engine):
"""Sets the cursor to the player when this handler is constructed."""
super().__init__(engine)
player = self.engine.player
engine.mouse_location = player.x, player.y
def on_render(self, console: tcod.Console) -> None:
"""Highlight the tile under the cursor."""
super().on_render(console)
x, y = self.engine.mouse_location
console.tiles_rgb["bg"][x, y] = color.white
console.tiles_rgb["fg"][x, y] = color.black
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]:
"""Check for key movement or confirmation keys."""
key = event.sym
if key in MOVE_KEYS:
modifier = 1 # Holding modifier keys will speed up key movement
if event.mod & (tcod.event.KMOD_LSHIFT | tcod.event.KMOD_RSHIFT):
modifier *= 5
if event.mod & (tcod.event.KMOD_LCTRL | tcod.event.KMOD_RCTRL):
modifier *= 10
if event.mod & (tcod.event.KMOD_LALT | tcod.event.KMOD_RALT):
modifier *= 20
x, y = self.engine.mouse_location
dx, dy = MOVE_KEYS[key]
x += dx * modifier
y += dy * modifier
# Clamp the cursor index to the map size.
x = max(0, min(x, self.engine.game_map.width - 1))
y = max(0, min(y, self.engine.game_map.height - 1))
self.engine.mouse_location = x, y
return None
elif key in CONFIRM_KEYS:
return self.on_index_selected(*self.engine.mouse_location)
return super().ev_keydown(event)
def ev_mousebuttondown(self, event: tcod.event.MouseButtonDown) -> Optional[Action]:
"""Left click confirms a selection."""
if self.engine.game_map.in_bounds(*event.tile):
if event.button == 1:
return self.on_index_selected(*event.tile)
return super().ev_mousebuttondown(event)
@overload
def on_index_selected(self, x: int, y: int) -> Optional[Action]:
"""Called when an index is selected."""
class LookHandler(SelectIndexHandler):
"""Lets the player look around using the keyboard."""
def on_index_selected(self, x: int, y: int) -> None:
"""Return to main handler."""
self.engine.event_handler = MainGameEventHandler(self.engine)
class MainGameEventHandler(EventHandler):
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]:
action: Optional[Action] = None
@ -252,6 +321,8 @@ class MainGameEventHandler(EventHandler):
self.engine.event_handler = InventoryActivateHandler(self.engine)
elif key == tcod.event.K_d:
self.engine.event_handler = InventoryDropHandler(self.engine)
elif key == tcod.event.K_SLASH:
self.engine.event_handler = LookHandler(self.engine)
# No valid key was pressed
return action