Search code examples
eventsinputsdlkey

Inputs in SDL (on key pressed)


I would like to know how can I detect the press of a key or release of a key in a while loop in SDL. Now, I know you can get the events with SDL like OnKeyPressed, OnKeyReleased, OnKeyHit, etc, but I want to know how to build functions like 'KeyPressed' that returns a boolean, instead of being an event. Example:

while not KeyHit( KEY_ESC ) 
{
//Code here
}

Solution

  • I know you have already selected an answer.. but here is some actual code of how I typically do it with one array. :)

    first define this somewhere.

    bool KEYS[322];  // 322 is the number of SDLK_DOWN events
        
    for(int i = 0; i < 322; i++) { // init them all to false
        KEYS[i] = false;
    }
        
    SDL_EnableKeyRepeat(0,0); // you can configure this how you want, but it makes it nice for when you want to register a key continuously being held down
    

    Then later, create a keyboard() function which will register keyboard input

    void keyboard() {
        // message processing loop
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            // check for messages
            switch (event.type) {
                // exit if the window is closed
            case SDL_QUIT:
                game_state = 0; // set game state to done,(do what you want here)
                break;
                // check for keypresses
            case SDL_KEYDOWN:
                KEYS[event.key.keysym.sym] = true;
                break;
            case SDL_KEYUP:
                KEYS[event.key.keysym.sym] = false;
                break;
            default:
                break;
            }
        } // end of message processing
    }
    

    Then when you actually want to use the keyboard input i.e. a handleInput() function, it may look something like this:

    void handleInput() {
        if(KEYS[SDLK_LEFT]) { // move left
            if(player->x - player->speed >= 0) {
                player->x -= player->speed;
            }
        }
        if(KEYS[SDLK_RIGHT]) { // move right
            if(player->x + player->speed <= screen->w) {
                player->x += player->speed;
            }
        }
        if(KEYS[SDLK_UP]) { // move up
            if(player->y - player->speed >= 0) {
                player->y -= player->speed;
            }
        }
        if(KEYS[SDLK_DOWN]) { // move down
            if(player->y + player->speed <= screen->h) {
                player->y += player->speed;
            }
        }
        if(KEYS[SDLK_s]) { // shoot 
            if(SDL_GetTicks() - player->lastShot > player->shotDelay) {
                shootbeam(player->beam);
            }
        }
        if(KEYS[SDLK_q]) {
            if(player->beam == PLAYER_BEAM_CHARGE) {
                player->beam = PLAYER_BEAM_NORMAL;
            } else {
                player->beam = PLAYER_BEAM_CHARGE;
            }
        }
        if(KEYS[SDLK_r]) {
            reset();
        }
        
        if(KEYS[SDLK_ESCAPE]) {
            gamestate = 0;
        }
    }
    

    And of course you can easily do what you're wanting to do

    while(KEYS[SDLK_s]) {
        // do something
        keyboard(); // don't forget to redetect which keys are being pressed!
    }
    

    **Updated version on my website: ** For the sake of not posting a lot of source code, you can view a complete SDL Keyboard class in C++ that supports

    1. Single Key Input
    2. Simultaneous Key Combos (Keys all pressed in any order)
    3. Sequential Key Combonations (Keys all pressed in specific order)

    http://kennycason.com/posts/2009-09-20-sdl-simple-space-shooter-game-demo-part-i.html (if you have any problems, let me know)