Search code examples
c++controls2d-gamesallegro

Change game controls in game


I'm programming game in C++ and Allegro 5, and I wanted to make controls settings. So if player wants, he can change controls in settings menu (in game).

I have this code:

while(!exit)
   {
       ALLEGRO_EVENT ev;
       al_wait_for_event(e_queue, &ev);

       if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
       {
           switch(ev.keyboard.keycode)
           {
           case ALLEGRO_KEY_DOWN:
                       //player goes down...
               break;
           case ALLEGRO_KEY_UP:
                       //player goes up...
               break;
           case ALLEGRO_KEY_LEFT:
                       //player goes left...
               break;
           case ALLEGRO_KEY_RIGHT:
                       //player goes right...
               break;
           case ALLEGRO_KEY_SPACE:
               break;
           default:
               break;
           }
       }
 ...
}

I thought, that I can make variable of ALLEGRO KEY CODE (i dont know if type like this exists) type, which has key code (for example ALLEGRO_KEY_LEFT), and than replace this code with:

...
allegro key code       keyUP;
allegro key code       keyDOWN;
...
       while(!exit)
   {
       ALLEGRO_EVENT ev;
       al_wait_for_event(e_queue, &ev);

       if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
       {
           switch(ev.keyboard.keycode)
           {
       case keyDOWN:
           break;
       case keyUP:
           break;
       case keyLEFT:
           break;
       case keyRIGHT:
           break;
       case keySPACE:
               break;
           default:
               break;
           }
       }
}

and add in settings something like this:

//set 'UP' key
           switch(ev.keyboard.keycode)
           {
                   case ALLEGRO_KEY_A:
                      keyUP = ALLEGRO_KEY_A;
                      break;
                   case ALLEGRO_KEY_B:
                      keyUP = ALLEGRO_KEY_B;
                      break;
                   case ALLEGRO_KEY_UP:
                      keyUP = ALLEGRO_KEY_UP;
                      break;
                   ...
           }
       }

The point is, I don't know what type store things like ALLEGRO_KEY_UP, DOWN ...

Thanks!


Solution

  • I would have two maps, one that maps a function name to a function, and one that maps a key to either the function name or the function. When the user want to remap keys, change the second map.

    It could be something like

    std::unordered_map<std::string, std::function<void()>> function_map;
    function_map["up"]   = std::bind(&functionForUp);
    function_map["down"] = std::bind(&functionForDown);
    function_map["jump"] = std::bind(&functionForJump);
    // etc.
    
    std::unordered_map<int, std::string> key_map;
    key_map[ALLEGRO_KEY_UP]    = "up";
    key_map[ALLEGRO_KEY_DOWN]  = "down";
    key_map[ALLEGRO_KEY_SPACE] = "jump";
    // etc.
    

    To call the function for a specific key, use e.g.

    function_map[key_map[ev.keyboard.keycode]]();
    

    This allows you to change the key_map at will:

    key_map[ALLEGRO_KEY_J] = "jump";
    

    References: