# Input System SimVX provides a unified input system for keyboard, mouse, gamepad, and touch. All bindings use typed enums — no raw strings. ## Input Actions Actions are named bindings that decouple game logic from specific keys: ```python from simvx.core import InputMap, Key, MouseButton, JoyButton, Input # Bind actions to keys (accepts Key, MouseButton, or JoyButton) InputMap.add_action("jump", [Key.SPACE, JoyButton.A]) InputMap.add_action("shoot", [MouseButton.LEFT]) InputMap.add_action("move_left", [Key.A, Key.LEFT]) InputMap.add_action("move_right", [Key.D, Key.RIGHT]) # Query in process() class Player(Node): def process(self, dt): if Input.is_action_just_pressed("jump"): self.jump() if Input.is_action_pressed("shoot"): self.fire() ``` ### Action Queries | Method | Returns | Description | |--------|---------|-------------| | `Input.is_action_pressed(name)` | `bool` | True while any bound key is held | | `Input.is_action_just_pressed(name)` | `bool` | True on the frame the action activates | | `Input.is_action_just_released(name)` | `bool` | True on the frame the action deactivates | | `Input.get_action_strength(name)` | `float` | 0.0–1.0 (1.0 when pressed for digital keys, analog for axes) | | `Input.get_strength(name)` | `float` | Alias for `get_action_strength` | ### Vector Input For directional movement, `get_vector()` and `get_axis()` combine multiple actions into a single value: ```python # Returns a normalised Vec2 from four directional actions direction = Input.get_vector("move_left", "move_right", "move_up", "move_down") self.position += direction * speed * dt # Returns a float from two opposing actions (-1 to 1) horizontal = Input.get_axis("move_left", "move_right") ``` ## InputMap `InputMap` manages action-to-binding mappings. It is a class-level singleton. | Method | Description | |--------|-------------| | `add_action(name, bindings)` | Register an action with a list of key/button bindings | | `remove_action(name)` | Remove an action and all its bindings | | `add_binding(name, binding)` | Add a binding to an existing action | | `remove_binding(name, binding)` | Remove a specific binding from an action | | `has_action(name)` | Check if an action exists | | `get_actions()` | List all registered action names | | `get_bindings(name)` | Get all bindings for an action | | `clear()` | Remove all actions | ### InputBinding For advanced bindings (gamepad axes, deadzones), use `InputBinding` directly: ```python from simvx.core import InputBinding, JoyAxis InputMap.add_action("move_left", [ Key.A, Key.LEFT, InputBinding(joy_axis=JoyAxis.LEFT_X, joy_axis_positive=False, deadzone=0.2), ]) ``` ## Direct Key/Mouse Queries For non-action-based input (debug tools, editor code): ```python # Keyboard Input.is_key_pressed(Key.ESCAPE) Input.is_key_just_pressed(Key.F3) # Mouse Input.is_mouse_button_pressed(MouseButton.LEFT) pos = Input.get_mouse_position() # Vec2 delta = Input.get_mouse_delta() # Vec2 (frame-to-frame movement) scroll_x, scroll_y = Input.get_scroll_delta() ``` ### Mouse Capture Control cursor visibility and confinement: ```python from simvx.core import MouseCaptureMode Input.set_mouse_capture_mode(MouseCaptureMode.CAPTURED) # FPS-style Input.set_mouse_capture_mode(MouseCaptureMode.VISIBLE) # Normal ``` | Mode | Description | |------|-------------| | `VISIBLE` | Normal cursor | | `HIDDEN` | Cursor hidden but moves freely | | `CAPTURED` | Cursor hidden and locked to window (FPS cameras) | | `CONFINED` | Cursor visible but confined to window | ## Gamepad ```python from simvx.core import JoyButton, JoyAxis # Digital buttons if Input.is_gamepad_pressed(button=JoyButton.A): self.jump() # Analog sticks (returns Vec2) stick = Input.get_gamepad_vector(stick="left") self.velocity = Vec3(stick.x, 0, stick.y) * speed # Raw axis value (-1.0 to 1.0) trigger = Input.get_gamepad_axis(axis=JoyAxis.RIGHT_TRIGGER) ``` ## Enums | Enum | Examples | |------|---------| | `Key` | `SPACE`, `ESCAPE`, `ENTER`, `TAB`, `A`–`Z`, `F1`–`F12`, `UP`/`DOWN`/`LEFT`/`RIGHT` | | `MouseButton` | `LEFT`, `RIGHT`, `MIDDLE`, `BUTTON_4`, `BUTTON_5` | | `JoyButton` | `A`, `B`, `X`, `Y`, `LEFT_BUMPER`, `RIGHT_BUMPER`, `START`, `BACK`, `DPAD_UP`/`DOWN`/`LEFT`/`RIGHT` | | `JoyAxis` | `LEFT_X`, `LEFT_Y`, `RIGHT_X`, `RIGHT_Y`, `LEFT_TRIGGER`, `RIGHT_TRIGGER` | ## Input Events For UI widgets and event-driven handling, SimVX provides event objects: - **`InputEventKey`** — `key`, `pressed`, `echo`, `shift`, `ctrl`, `alt`, `handled` - **`InputEventMouse`** — `button`, `pressed`, `position`, `shift`, `ctrl`, `alt`, `handled` Set `event.handled = True` to consume an event and prevent further propagation. UI widgets receive input first — if a focused widget consumes the event, game nodes don't see it. ## API Reference See {py:mod}`simvx.core.input` for the complete input API.