Add cursor mode to look around using keyboard controls
This commit is contained in:
parent
5b5f49bf6b
commit
bebd9d617e
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user