/******************************************************************************************* * * raylib [core] example - input actions * * Example complexity rating: [★★☆☆] 2/4 * * Example originally created with raylib 5.5, last time updated with raylib 5.6 * * Example contributed by Jett (@JettMonstersGoBoom) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * * Copyright (c) 2025 Jett (@JettMonstersGoBoom) * ********************************************************************************************/ // Simple example for decoding input as actions, allowing remapping of input to different keys or gamepad buttons // For example instead of using `IsKeyDown(KEY_LEFT)`, you can use `IsActionDown(ACTION_LEFT)` // which can be reassigned to e.g. KEY_A and also assigned to a gamepad button. the action will trigger with either gamepad or keys #include "raylib.h" //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- typedef enum ActionType { NO_ACTION = 0, ACTION_UP, ACTION_DOWN, ACTION_LEFT, ACTION_RIGHT, ACTION_FIRE, MAX_ACTION } ActionType; // Key and button inputs typedef struct ActionInput { int key; int button; } ActionInput; //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- static int gamepadIndex = 0; // Gamepad default index static ActionInput actionInputs[MAX_ACTION] = { 0 }; //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- static bool IsActionPressed(int action); // Check action key/button pressed static bool IsActionReleased(int action); // Check action key/button released static bool IsActionDown(int action); // Check action key/button down static void SetActionsDefault(void); // Set the "default" keyset static void SetActionsCursor(void); // Set the "alternate" keyset //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ int main(void) { // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [core] example - input actions"); // Set default actions char actionSet = 0; SetActionsDefault(); Vector2 position = (Vector2){ 400.0f, 200.0f }; Vector2 size = (Vector2){ 40.0f, 40.0f }; SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- gamepadIndex = 0; // set this to gamepad being checked if (IsActionDown(ACTION_UP)) position.y -= 2; if (IsActionDown(ACTION_DOWN)) position.y += 2; if (IsActionDown(ACTION_LEFT)) position.x -= 2; if (IsActionDown(ACTION_RIGHT)) position.x += 2; if (IsActionPressed(ACTION_FIRE)) { position.x = (screenWidth-size.x)/2; position.y = (screenHeight-size.y)/2; } // Switch control scheme by pressing TAB if (IsKeyPressed(KEY_TAB)) { actionSet = !actionSet; if (actionSet == 0) SetActionsDefault(); else SetActionsCursor(); } //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(GRAY); DrawRectangleV(position, size, RED); DrawText((actionSet == 0)? "Current input set: WASD (default)" : "Current input set: Cursor", 10, 10, 20, WHITE); DrawText("Use TAB key to toggles Actions keyset", 10, 50, 20, GREEN); EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; } //---------------------------------------------------------------------------------- // Module Functions Definition //---------------------------------------------------------------------------------- // Check action key/button pressed // NOTE: Combines key pressed and gamepad button pressed in one action static bool IsActionPressed(int action) { bool result = false; if (action < MAX_ACTION) result = (IsKeyPressed(actionInputs[action].key) || IsGamepadButtonPressed(gamepadIndex, actionInputs[action].button)); return result; } // Check action key/button released // NOTE: Combines key released and gamepad button released in one action static bool IsActionReleased(int action) { bool result = false; if (action < MAX_ACTION) result = (IsKeyReleased(actionInputs[action].key) || IsGamepadButtonReleased(gamepadIndex, actionInputs[action].button)); return result; } // Check action key/button down // NOTE: Combines key down and gamepad button down in one action static bool IsActionDown(int action) { bool result = false; if (action < MAX_ACTION) result = (IsKeyDown(actionInputs[action].key) || IsGamepadButtonDown(gamepadIndex, actionInputs[action].button)); return result; } // Set the "default" keyset // NOTE: Here WASD and gamepad buttons on the left side for movement static void SetActionsDefault(void) { actionInputs[ACTION_UP].key = KEY_W; actionInputs[ACTION_DOWN].key = KEY_S; actionInputs[ACTION_LEFT].key = KEY_A; actionInputs[ACTION_RIGHT].key = KEY_D; actionInputs[ACTION_FIRE].key = KEY_SPACE; actionInputs[ACTION_UP].button = GAMEPAD_BUTTON_LEFT_FACE_UP; actionInputs[ACTION_DOWN].button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; actionInputs[ACTION_LEFT].button = GAMEPAD_BUTTON_LEFT_FACE_LEFT; actionInputs[ACTION_RIGHT].button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; actionInputs[ACTION_FIRE].button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; } // Set the "alternate" keyset // NOTE: Here cursor keys and gamepad buttons on the right side for movement static void SetActionsCursor(void) { actionInputs[ACTION_UP].key = KEY_UP; actionInputs[ACTION_DOWN].key = KEY_DOWN; actionInputs[ACTION_LEFT].key = KEY_LEFT; actionInputs[ACTION_RIGHT].key = KEY_RIGHT; actionInputs[ACTION_FIRE].key = KEY_SPACE; actionInputs[ACTION_UP].button = GAMEPAD_BUTTON_RIGHT_FACE_UP; actionInputs[ACTION_DOWN].button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; actionInputs[ACTION_LEFT].button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT; actionInputs[ACTION_RIGHT].button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; actionInputs[ACTION_FIRE].button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; }