Gamepad

Handle the state of connected gamepads.

Show text for most button presses.

The state of the gamepads is checked in the render function, which is something you normally would not want to do, you would want to check it in the update function. But for this example that doesn’t matter because the update delta time is low enough that it lasts multiple render functions.

Source

use chuot::{Config, Context, Game, GamepadAxis, GamepadButton};

/// Define empty game state.
struct GameState;

impl Game for GameState {
    /// Show some text with gamepad buttons being pressed.
    fn render(&mut self, ctx: Context) {
        // Position of the next line of text
        let mut line_y = 2.0;

        // Get all IDs of connected gamepads
        let connected_gamepad_ids = ctx.gamepad_ids();

        if connected_gamepad_ids.is_empty() {
            ctx.text("Beachball", "Activate or\nconnect a gamepad")
                .use_ui_camera()
                .translate((2.0, line_y))
                .draw();
        }

        // Show the D-Pad button presses for each connected gamepad
        for (index, gamepad_id) in connected_gamepad_ids.iter().enumerate() {
            // Draw the gamepad index
            ctx.text("Beachball", &format!("Connected gamepad {}:", index + 1))
                .use_ui_camera()
                .translate((2.0, line_y))
                .draw();
            line_y += 12.0;

            // Show the button states
            for (button, name) in [
                (GamepadButton::North, "North"),
                (GamepadButton::South, "South"),
                (GamepadButton::East, "East"),
                (GamepadButton::West, "West"),
                (GamepadButton::C, "C"),
                (GamepadButton::Z, "Z"),
                (GamepadButton::LeftTrigger, "Left Trigger"),
                (GamepadButton::LeftTrigger2, "Left Trigger 2"),
                (GamepadButton::RightTrigger, "Right Trigger"),
                (GamepadButton::RightTrigger2, "Right Trigger 2"),
                (GamepadButton::Select, "Select"),
                (GamepadButton::Start, "Start"),
                (GamepadButton::Mode, "Mode"),
                (GamepadButton::LeftThumb, "Left Thumb"),
                (GamepadButton::RightThumb, "Right Thumb"),
                (GamepadButton::DPadUp, "D-Pad Up"),
                (GamepadButton::DPadDown, "D-Pad Down"),
                (GamepadButton::DPadLeft, "D-Pad Left"),
                (GamepadButton::DPadRight, "D-Pad Right"),
            ] {
                // Get the state of the button
                let state = if ctx.gamepad_button_pressed(*gamepad_id, button) == Some(true) {
                    Some("Pressed")
                } else if ctx.gamepad_button_released(*gamepad_id, button) == Some(true) {
                    Some("Released")
                } else if ctx.gamepad_button_held(*gamepad_id, button) == Some(true) {
                    Some("Held")
                } else {
                    None
                };

                // Show the button state text
                if let Some(state) = state {
                    ctx.text("Beachball", &format!(" {name}: {state}"))
                        .use_ui_camera()
                        .translate((2.0, line_y))
                        .draw();
                    line_y += 12.0;
                }

                // Show the button value if an inbetween value is received
                if let Some(value) = ctx.gamepad_button_value(*gamepad_id, button) {
                    // Only show when engaged
                    if value > 0.0 && value < 1.0 {
                        ctx.text("Beachball", &format!(" {name}: {value:.1}"))
                            .use_ui_camera()
                            .translate((2.0, line_y))
                            .draw();
                        line_y += 12.0;
                    }
                }
            }

            // Show the axis values
            for (axis, name) in [
                (GamepadAxis::LeftStickX, "Left Stick X"),
                (GamepadAxis::LeftStickY, "Left Stick Y"),
                (GamepadAxis::LeftZ, "Left Z"),
                (GamepadAxis::RightStickX, "Right Stick X"),
                (GamepadAxis::RightStickY, "Right Stick Y"),
                (GamepadAxis::RightZ, "Right Z"),
                (GamepadAxis::DPadX, "D-Pad X"),
                (GamepadAxis::DPadY, "D-Pad Y"),
            ] {
                if let Some(value) = ctx.gamepad_axis(*gamepad_id, axis) {
                    // Only show when engaged
                    if value != 0.0 {
                        ctx.text("Beachball", &format!(" {name}: {value:.1}"))
                            .use_ui_camera()
                            .translate((2.0, line_y))
                            .draw();
                        line_y += 12.0;
                    }
                }
            }
        }
    }

    /// Do nothing during the update loop.
    fn update(&mut self, _ctx: Context) {}
}

/// Run the game.
fn main() {
    // Start the game with defaults for the window
    GameState.run(
        chuot::load_assets!(),
        Config::default()
            .with_buffer_size((240.0, 192.0))
            .with_scaling(3.0)
            // Ensure the gamepads state only updates 10 times every frame for this example
            .with_update_delta_time(0.1),
    );
}

Compatibility

Chuột VersionExample Works
0.3.0🚫
Unreleased