tiramisu/input
Input module - keyboard, mouse, gamepad, and touch input handling.
Input state is automatically updated each frame and passed to your update
function
via the Context
. Query the input state to respond to player actions.
Quick Example
import tiramisu/input
fn update(model, msg, ctx) {
// Check if player is pressing W to move forward
let move_forward = case input.is_key_pressed(ctx.input, input.KeyW) {
True -> 1.0
False -> 0.0
}
// Check mouse button
let shooting = input.is_left_button_pressed(ctx.input)
// Update model based on input
Model(..model, position: move_player(model.position, move_forward))
}
Types
Buffered input for more forgiving gameplay
Buffers action presses for a specified number of frames, allowing players to press inputs slightly before they’re valid (e.g., jump before landing).
Example
// In your model
pub type Model {
Model(
buffered_input: input.BufferedInput(Action),
// ...
)
}
// In init
fn init(_flags) {
let buffered = input.with_buffer(buffer_frames: 5)
Model(buffered_input: buffered, ...)
}
// In update
fn update(model, msg, ctx) {
// Update buffer each frame
let buffered = input.update_buffer(
model.buffered_input,
ctx.input,
bindings,
)
// Check if action was pressed within buffer window
let can_jump = input.was_action_pressed_buffered(buffered, bindings, Jump)
Model(..model, buffered_input: buffered)
}
pub opaque type BufferedInput(action)
pub type ButtonState {
ButtonState(
pressed: Bool,
just_pressed: Bool,
just_released: Bool,
)
}
Constructors
-
ButtonState( pressed: Bool, just_pressed: Bool, just_released: Bool, )
pub type GamepadAxis {
LeftStickX
LeftStickY
RightStickX
RightStickY
}
Constructors
-
LeftStickX
-
LeftStickY
-
RightStickX
-
RightStickY
Gamepad button enumeration (standard mapping)
pub type GamepadButton {
ButtonA
ButtonB
ButtonX
ButtonY
LeftBumper
RightBumper
LeftTrigger
RightTrigger
Select
Start
LeftStick
RightStick
DPadUp
DPadDown
DPadLeft
DPadRight
HomeButton
}
Constructors
-
ButtonA
-
ButtonB
-
ButtonX
-
ButtonY
-
LeftBumper
-
RightBumper
-
LeftTrigger
-
RightTrigger
-
Select
-
Start
-
LeftStick
-
RightStick
-
DPadUp
-
DPadDown
-
DPadLeft
-
DPadRight
-
HomeButton
pub type GamepadState {
GamepadState(
connected: Bool,
buttons: List(Float),
axes: List(Float),
)
}
Constructors
-
GamepadState( connected: Bool, buttons: List(Float), axes: List(Float), )
Arguments
- buttons
-
Buttons: Values clamped between 0.0 and 1.0
Input bindings that map inputs to user-defined actions
Generic over action type, so you can define your own action enum:
pub type Action {
Jump
MoveForward
Shoot
}
let bindings = input.new_bindings()
|> input.bind_key(input.Space, Jump)
|> input.bind_key(input.KeyW, MoveForward)
|> input.bind_mouse_button(input.LeftButton, Shoot)
pub opaque type InputBindings(action)
Input state for all input devices (automatically updated each frame).
Access via context.input
in your update
function.
pub opaque type InputState
Common keyboard codes (standard KeyboardEvent.code values)
pub type Key {
KeyA
KeyB
KeyC
KeyD
KeyE
KeyF
KeyG
KeyH
KeyI
KeyJ
KeyK
KeyL
KeyM
KeyN
KeyO
KeyP
KeyQ
KeyR
KeyS
KeyT
KeyU
KeyV
KeyW
KeyX
KeyY
KeyZ
Digit0
Digit1
Digit2
Digit3
Digit4
Digit5
Digit6
Digit7
Digit8
Digit9
F1
F2
F3
F4
F5
F6
F7
F8
F9
F10
F11
F12
ArrowUp
ArrowDown
ArrowLeft
ArrowRight
ShiftLeft
ShiftRight
ControlLeft
ControlRight
AltLeft
AltRight
MetaLeft
MetaRight
Space
Enter
Escape
Tab
Backspace
Delete
Insert
Home
End
PageUp
PageDown
CapsLock
Minus
Equal
BracketLeft
BracketRight
Backslash
Semicolon
Quote
Comma
Period
Slash
Backquote
Numpad0
Numpad1
Numpad2
Numpad3
Numpad4
Numpad5
Numpad6
Numpad7
Numpad8
Numpad9
NumpadAdd
NumpadSubtract
NumpadMultiply
NumpadDivide
NumpadDecimal
NumpadEnter
NumLock
AudioVolumeUp
AudioVolumeDown
AudioVolumeMute
MediaPlayPause
MediaStop
MediaTrackNext
MediaTrackPrevious
PrintScreen
ScrollLock
Pause
ContextMenu
Custom(String)
}
Constructors
-
KeyA
-
KeyB
-
KeyC
-
KeyD
-
KeyE
-
KeyF
-
KeyG
-
KeyH
-
KeyI
-
KeyJ
-
KeyK
-
KeyL
-
KeyM
-
KeyN
-
KeyO
-
KeyP
-
KeyQ
-
KeyR
-
KeyS
-
KeyT
-
KeyU
-
KeyV
-
KeyW
-
KeyX
-
KeyY
-
KeyZ
-
Digit0
-
Digit1
-
Digit2
-
Digit3
-
Digit4
-
Digit5
-
Digit6
-
Digit7
-
Digit8
-
Digit9
-
F1
-
F2
-
F3
-
F4
-
F5
-
F6
-
F7
-
F8
-
F9
-
F10
-
F11
-
F12
-
ArrowUp
-
ArrowDown
-
ArrowLeft
-
ArrowRight
-
ShiftLeft
-
ShiftRight
-
ControlLeft
-
ControlRight
-
AltLeft
-
AltRight
-
MetaLeft
-
MetaRight
-
Space
-
Enter
-
Escape
-
Tab
-
Backspace
-
Delete
-
Insert
-
Home
-
End
-
PageUp
-
PageDown
-
CapsLock
-
Minus
-
Equal
-
BracketLeft
-
BracketRight
-
Backslash
-
Semicolon
-
Quote
-
Comma
-
Period
-
Slash
-
Backquote
-
Numpad0
-
Numpad1
-
Numpad2
-
Numpad3
-
Numpad4
-
Numpad5
-
Numpad6
-
Numpad7
-
Numpad8
-
Numpad9
-
NumpadAdd
-
NumpadSubtract
-
NumpadMultiply
-
NumpadDivide
-
NumpadDecimal
-
NumpadEnter
-
NumLock
-
AudioVolumeUp
-
AudioVolumeDown
-
AudioVolumeMute
-
MediaPlayPause
-
MediaStop
-
MediaTrackNext
-
MediaTrackPrevious
-
PrintScreen
-
ScrollLock
-
Pause
-
ContextMenu
-
Custom(String)
pub opaque type KeyboardState
Mouse button enumeration for action mapping
pub type MouseButton {
LeftButton
RightButton
MiddleButton
}
Constructors
-
LeftButton
-
RightButton
-
MiddleButton
pub opaque type MouseState
pub type Touch {
Touch(id: Int, x: Float, y: Float)
}
Constructors
-
Touch(id: Int, x: Float, y: Float)
Values
pub fn bind_gamepad_button(
bindings: InputBindings(action),
button: GamepadButton,
action: action,
) -> InputBindings(action)
Bind a gamepad button to an action
pub fn bind_key(
bindings: InputBindings(action),
key: Key,
action: action,
) -> InputBindings(action)
Bind a keyboard key to an action
Example
let bindings = input.new_bindings()
|> input.bind_key(input.Space, Jump)
|> input.bind_key(input.KeyW, MoveForward)
pub fn bind_mouse_button(
bindings: InputBindings(action),
button: MouseButton,
action: action,
) -> InputBindings(action)
Bind a mouse button to an action
pub fn clear_buffer(
buffered: BufferedInput(action),
) -> BufferedInput(action)
Clear all buffered actions
Useful when switching game states or when you want to reset the buffer.
pub fn consume_buffered_action(
buffered: BufferedInput(action),
action: action,
) -> BufferedInput(action)
Consume a buffered action (remove it from buffer)
Use this when you’ve acted on a buffered input to prevent it from being used multiple times.
Example
let can_jump = is_grounded
&& input.was_action_pressed_buffered(buffered, Jump)
case can_jump {
True -> {
// Perform jump
let buffered = input.consume_buffered_action(buffered, Jump)
// ...
}
False -> // ...
}
pub fn gamepad_axis(
input: InputState,
gamepad_index: Int,
axis: GamepadAxis,
) -> Float
Get gamepad axis value
pub fn gamepad_button(
input: InputState,
gamepad_index: Int,
button: GamepadButton,
) -> Float
Get gamepad button value
pub fn get_action_value(
input: InputState,
bindings: InputBindings(action),
action: action,
) -> Float
Get the analog value (0.0 to 1.0) for an action
Useful for actions that can have analog input like gamepad triggers. Returns 1.0 for digital inputs (keyboard/mouse) when pressed, 0.0 when not pressed.
pub fn get_axis_with_deadzone(
input: InputState,
gamepad_index: Int,
axis: GamepadAxis,
deadzone: Float,
) -> Float
Get axis value with dead zone applied
pub fn get_primary_axis(
input: InputState,
axis: GamepadAxis,
) -> Float
Convenience: Get axis value on primary gamepad
pub fn get_primary_button(
input: InputState,
button: GamepadButton,
) -> Float
Convenience: Get button value on primary gamepad
pub fn is_action_just_pressed(
input: InputState,
bindings: InputBindings(action),
action: action,
) -> Bool
Check if an action was just pressed this frame
Returns True if any input bound to this action was just pressed.
pub fn is_action_just_released(
input: InputState,
bindings: InputBindings(action),
action: action,
) -> Bool
Check if an action was just released this frame
pub fn is_action_pressed(
input: InputState,
bindings: InputBindings(action),
action: action,
) -> Bool
Check if an action is currently pressed
Returns True if any input bound to this action is pressed.
Example
if input.is_action_pressed(ctx.input, bindings, Jump) {
// Player wants to jump
}
pub fn is_gamepad_button_pressed(
input: InputState,
gamepad_index: Int,
button: GamepadButton,
) -> Bool
Check if gamepad button is pressed
pub fn is_gamepad_connected(
input: InputState,
index: Int,
) -> Bool
Check if gamepad at index is connected
pub fn is_key_just_pressed(input: InputState, key: Key) -> Bool
Check if a key was just pressed this frame
pub fn is_key_just_released(input: InputState, key: Key) -> Bool
Check if a key was just released this frame
pub fn is_key_pressed(input: InputState, key: Key) -> Bool
Check if a key is currently pressed
pub fn is_left_button_just_pressed(input: InputState) -> Bool
Check if left mouse button was just pressed
pub fn is_left_button_pressed(input: InputState) -> Bool
Check if left mouse button is pressed
pub fn is_left_stick_active(
input: InputState,
gamepad_index: Int,
threshold: Float,
) -> Bool
Check if left stick is moved in any direction
pub fn is_primary_connected(input: InputState) -> Bool
Convenience: Check if primary gamepad (index 0) is connected
pub fn is_primary_gamepad_button_pressed(
input: InputState,
button: GamepadButton,
) -> Bool
Convenience: Check button on primary gamepad
pub fn is_right_button_just_pressed(input: InputState) -> Bool
Check if right mouse button was just pressed
pub fn is_right_button_pressed(input: InputState) -> Bool
Check if right mouse button is pressed
pub fn is_right_stick_active(
input: InputState,
gamepad_index: Int,
threshold: Float,
) -> Bool
Check if right stick is moved in any direction
pub fn new() -> InputState
pub fn new_bindings() -> InputBindings(action)
Create a new empty input bindings configuration
pub fn touches_just_ended(input: InputState) -> List(Touch)
Get touches that just ended
pub fn touches_just_started(input: InputState) -> List(Touch)
Get touches that just started
pub fn update_buffer(
buffered: BufferedInput(action),
input: InputState,
bindings: InputBindings(action),
) -> BufferedInput(action)
Update the input buffer each frame
Call this once per frame in your update function to:
- Add newly pressed actions to the buffer
- Remove expired actions from the buffer
Example
let buffered = input.update_buffer(
model.buffered_input,
ctx.input,
bindings,
)
pub fn was_action_pressed_buffered(
buffered: BufferedInput(action),
action: action,
) -> Bool
Check if an action was pressed within the buffer window
Returns True if the action was pressed in the last N frames (where N is buffer_frames). This allows for more forgiving input timing.
Example
// Allow jump input to be buffered - player can press jump slightly
// before landing and it will still work
let can_jump = is_grounded
&& input.was_action_pressed_buffered(buffered, bindings, Jump)
pub fn with_buffer(
buffer_frames buffer_frames: Int,
) -> BufferedInput(action)
Create a new buffered input system