1+
2+ /*******************************************************************************************
3+ *
4+ * raylib [core_inputactionInputs] example - presents a simple API for remapping input to actions
5+ *
6+ * Example complexity rating: [★☆☆☆] 1/4
7+ *
8+ * Example originally created with raylib 5.5, last time updated with raylib 5.6
9+ *
10+ * Example contributed by MonstersGoBoom and reviewed by Ramon Santamaria (@raysan5)
11+ *
12+ * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
13+ * BSD-like license that allows static linking with closed source software
14+ *
15+ * Copyright (c) 2025 MonstersGoBoom
16+ *
17+ ********************************************************************************************/
18+
19+ /*
20+ Simple example for decoding input as actions, allowing remapping of input to different keys or gamepad buttons.
21+ for example instead of
22+ IsKeyDown(KEY_LEFT)
23+ you'd use
24+ IsActionDown(ACTION_LEFT)
25+ 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
26+ */
27+
28+
29+ #include <stdio.h>
30+ #include <stdlib.h>
31+ #include <stdbool.h>
32+ #include "raylib.h"
33+
34+ // add your own action types here
35+
36+ typedef enum ActionType
37+ {
38+ NO_ACTION ,
39+ ACTION_UP ,
40+ ACTION_DOWN ,
41+ ACTION_LEFT ,
42+ ACTION_RIGHT ,
43+ ACTION_FIRE ,
44+ MAX_ACTION
45+ } ActionType ;
46+
47+ // struct for key and button inputs
48+ typedef struct ActionInput
49+ {
50+ int key ;
51+ int button ;
52+ } ActionInput ;
53+
54+ // gamepad index, change this if you have multiple gamepads.
55+ int gamepadIndex = 0 ;
56+ static ActionInput actionInputs [MAX_ACTION ] = {0 };
57+
58+ // combines IsKeyPressed and IsGameButtonPressed to one action
59+ bool isActionPressed (int action )
60+ {
61+ if (action < MAX_ACTION )
62+ return (IsKeyPressed (actionInputs [action ].key ) || IsGamepadButtonPressed (gamepadIndex , actionInputs [action ].button ));
63+ return (false);
64+ }
65+
66+ // combines IsKeyReleased and IsGameButtonReleased to one action
67+ bool isActionReleased (int action )
68+ {
69+ if (action < MAX_ACTION )
70+ return (IsKeyReleased (actionInputs [action ].key ) || IsGamepadButtonReleased (gamepadIndex , actionInputs [action ].button ));
71+ return (false);
72+ }
73+
74+ // combines IsKeyDown and IsGameButtonDown to one action
75+ bool isActionDown (int action )
76+ {
77+ if (action < MAX_ACTION )
78+ return (IsKeyDown (actionInputs [action ].key ) || IsGamepadButtonDown (gamepadIndex , actionInputs [action ].button ));
79+ return (false);
80+ }
81+ // define the "default" keyset. here WASD and gamepad buttons on the left side for movement
82+ void DefaultActions ()
83+ {
84+ actionInputs [ACTION_UP ].key = KEY_W ;
85+ actionInputs [ACTION_DOWN ].key = KEY_S ;
86+ actionInputs [ACTION_LEFT ].key = KEY_A ;
87+ actionInputs [ACTION_RIGHT ].key = KEY_D ;
88+ actionInputs [ACTION_FIRE ].key = KEY_SPACE ;
89+
90+ actionInputs [ACTION_UP ].button = GAMEPAD_BUTTON_LEFT_FACE_UP ;
91+ actionInputs [ACTION_DOWN ].button = GAMEPAD_BUTTON_LEFT_FACE_DOWN ;
92+ actionInputs [ACTION_LEFT ].button = GAMEPAD_BUTTON_LEFT_FACE_LEFT ;
93+ actionInputs [ACTION_RIGHT ].button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT ;
94+ actionInputs [ACTION_FIRE ].button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN ;
95+ }
96+
97+ // define the "alternate" keyset. here Cursor Keys and gamepad buttons on the right side for movement
98+ void CursorActions ()
99+ {
100+ actionInputs [ACTION_UP ].key = KEY_UP ;
101+ actionInputs [ACTION_DOWN ].key = KEY_DOWN ;
102+ actionInputs [ACTION_LEFT ].key = KEY_LEFT ;
103+ actionInputs [ACTION_RIGHT ].key = KEY_RIGHT ;
104+ actionInputs [ACTION_FIRE ].key = KEY_SPACE ;
105+
106+ actionInputs [ACTION_UP ].button = GAMEPAD_BUTTON_RIGHT_FACE_UP ;
107+ actionInputs [ACTION_DOWN ].button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN ;
108+ actionInputs [ACTION_LEFT ].button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT ;
109+ actionInputs [ACTION_RIGHT ].button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT ;
110+ actionInputs [ACTION_FIRE ].button = GAMEPAD_BUTTON_LEFT_FACE_DOWN ;
111+ }
112+
113+ //------------------------------------------------------------------------------------
114+ // Program main entry point
115+ //------------------------------------------------------------------------------------
116+
117+ int main (int argc , char * * argv )
118+ {
119+ const int screenWidth = 800 ;
120+ const int screenHeight = 450 ;
121+
122+ InitWindow (screenWidth , screenHeight , "raylib [core] example - input via actions" );
123+ SetWindowState (FLAG_WINDOW_RESIZABLE );
124+ SetTargetFPS (60 );
125+
126+ // set default actions
127+ char actionSet = 0 ;
128+ DefaultActions ();
129+
130+ Vector2 position = (Vector2 ){100 , 100 };
131+ Vector2 size = (Vector2 ){32 , 32 };
132+
133+ while (!WindowShouldClose ()) // Detect window close button or ESC key
134+ {
135+ //----------------------------------------------------------------------------------
136+ BeginDrawing ();
137+ ClearBackground (DARKGRAY );
138+ DrawText (actionSet == 0 ? "WASD Default Set" : "Cursor Set" , 0 , 0 , 18 , WHITE );
139+ DrawText ("Tab key toggles keyset" , 0 , 18 , 18 , WHITE );
140+ DrawRectangleV (position , size , RED );
141+ EndDrawing ();
142+
143+ gamepadIndex = 0 ; // set this to gamepad being checked
144+ if (isActionDown (ACTION_UP ))
145+ position .y -= 2 ;
146+ if (isActionDown (ACTION_DOWN ))
147+ position .y += 2 ;
148+ if (isActionDown (ACTION_LEFT ))
149+ position .x -= 2 ;
150+ if (isActionDown (ACTION_RIGHT ))
151+ position .x += 2 ;
152+ if (isActionPressed (ACTION_FIRE ))
153+ {
154+ position .x = (screenWidth - size .x )/2 ;
155+ position .y = (screenHeight - size .y )/2 ;
156+ }
157+
158+ // switch control scheme by pressing TAB
159+ if (IsKeyPressed (KEY_TAB ))
160+ {
161+ actionSet = !actionSet ;
162+ if (actionSet == 0 )
163+ DefaultActions ();
164+ else
165+ CursorActions ();
166+ }
167+ //----------------------------------------------------------------------------------
168+ }
169+
170+ // De-Initialization
171+ //--------------------------------------------------------------------------------------
172+ CloseWindow (); // Close window and OpenGL context
173+ return 0 ;
174+ }
0 commit comments