Input & Callbacks
The Input & Callback System handles all user interaction and timed events in McRogueFace. It provides keyboard and mouse input through scene callbacks, and scheduled execution through timers.
Overview
McRogueFace uses a callback-based input model. Instead of polling for input in a game loop, you register callback functions that are invoked when events occur.
def on_key(key, state):
if key == "W" and state == "start":
move_player(0, -1)
scene.on_key = on_key
Objects
| Object | Purpose |
|---|---|
| Timer | Scheduled callbacks at intervals |
Keyboard Input
Keyboard input is handled through the scene’s on_key callback.
Key Callback Signature
def on_key(key: str, state: str) -> None:
pass
key: The key name (e.g., “W”, “Space”, “Return”, “Escape”)state: One of “start” (pressed), “repeat” (held), or “end” (released)
Example: Movement
def on_key(key, state):
if state != "start":
return
dx, dy = 0, 0
if key == "W" or key == "Up": dy = -1
elif key == "S" or key == "Down": dy = 1
elif key == "A" or key == "Left": dx = -1
elif key == "D" or key == "Right": dx = 1
if dx or dy:
new_x = player.x + dx
new_y = player.y + dy
if grid.at(new_x, new_y).walkable:
player.x, player.y = new_x, new_y
scene.on_key = on_key
Key Names
Common key names:
- Letters: “A” through “Z”
- Numbers: “0” through “9”
- Arrows: “Up”, “Down”, “Left”, “Right”
- Modifiers: “LShift”, “RShift”, “LControl”, “RControl”, “LAlt”, “RAlt”
- Special: “Space”, “Return”, “Escape”, “Tab”, “Backspace”
Mouse Input
Mouse input is handled through the scene’s on_mouse callback.
Mouse Callback Signature
def on_mouse(x: int, y: int, button: str, state: str) -> None:
pass
x,y: Mouse position in pixelsbutton: “left”, “right”, “middle”, or “none” (for movement)state: “start” (pressed), “end” (released), or “move”
Example: Click Detection
def on_mouse(x, y, button, state):
if button == "left" and state == "start":
# Convert pixel position to grid coordinates
grid_x = (x - grid.x) // (grid.tile_size * grid.zoom)
grid_y = (y - grid.y) // (grid.tile_size * grid.zoom)
print(f"Clicked tile: ({grid_x}, {grid_y})")
scene.on_mouse = on_mouse
UI Element Interaction
UI elements can have their own click handlers:
button = mcrfpy.Frame(pos=(100, 100), size=(120, 40))
button.on_click = lambda: print("Button clicked!")
Timers
Timers execute callbacks at specified intervals.
Creating Timers
# Call every 500ms
def update():
print("Timer tick!")
mcrfpy.Timer("update_timer", update, 500)
One-Shot Timers
For single execution, cancel the timer in the callback:
def delayed_action():
print("Delayed!")
mcrfpy.Timer.cancel("delay_timer")
mcrfpy.Timer("delay_timer", delayed_action, 1000)
Timer Control
# Pause a timer
mcrfpy.Timer.pause("update_timer")
# Resume a timer
mcrfpy.Timer.resume("update_timer")
# Cancel a timer
mcrfpy.Timer.cancel("update_timer")
Animation Timers
Timers are commonly used for animations:
frame = 0
def animate():
global frame
sprite.sprite_index = animation_frames[frame]
frame = (frame + 1) % len(animation_frames)
mcrfpy.Timer("animation", animate, 100) # 10 FPS animation
Scene Lifecycle
Scenes have lifecycle callbacks for initialization and cleanup.
on_enter
Called when a scene becomes active:
def on_enter():
print("Scene activated!")
# Initialize game state, start timers, etc.
scene.on_enter = on_enter
on_exit
Called when leaving a scene:
def on_exit():
print("Leaving scene")
# Clean up timers, save state, etc.
scene.on_exit = on_exit