11
\$\begingroup\$

I'm making a simple game, and one of the problems I encountered is the annoying delay when pressing a key continuously.

So basically, when I press (for a very long time) for example Up, my object will move 1 unit up, not move (for approx. 1 second), and then move continuously 1 unit up (without any delays).

Currently, I use this to move the object (SDL2):

while (SDL_PollEvent(&event))
{
    switch (event.type)
    {
    case SDL_KEYDOWN:
        switch (event.key.keysym.sym)
        {
        case SDLK_UP:
            //Move object 1 unit up
            break;
        //Other unrelated things omitted
        }
        break;
    //Omitted other cases
    }
}

What I would like to have is to remove the delay, so that the object can immediately move Up very quickly. Is there any way to do this?

\$\endgroup\$
19
\$\begingroup\$

By waiting for key-down events to be fired, you are likely at the mercy of the key event repeat rate that the OS controls (and which users can specify themselves).

Instead, you may want to call SDL_GetKeyboardState at the top of your game update loop (the part of the update that happens every frame, whether or not an event has come in) to get the state of the keyboard and check that to see if the up key is down or not during any individual frame.

\$\endgroup\$
  • \$\begingroup\$ Wouldn't it be better to listen to window messages? Using polling I sometimes miss very short key presses and this problem gets worse when the framerate is low. \$\endgroup\$ – Roy T. May 25 '16 at 11:53
  • \$\begingroup\$ @RoyT. It really depends on your game and the kind of action you want to trigger with the key. If the key-press is a one-off thing, Like an "action" key, which closes a dialog then a message queue is the right approach - you want to listen for an atomic event. - If on the other hand the key-status represents an ongoing state like a "move" key, the logic is usually while key UP is down move 30 units per second - and per second only makes sense when you have a measurable time between key down and up - usually more than one frame. \$\endgroup\$ – Falco May 25 '16 at 12:59
  • \$\begingroup\$ @RoyT. You could also listen to messages (and use them to update your own keyboard state array); I opted to suggest this approach for its simplicity. You can certainly write another answer though. The important part is just to avoid relying on OS messages for checking if the key is continuously down, because that's what chains you to the OS key repeat rate. \$\endgroup\$ – Josh May 25 '16 at 15:19
  • \$\begingroup\$ And by frame you mean game tick, not video frame, right? Because we're not being plebs and encoding game logic in the render loop. :-) \$\endgroup\$ – corsiKa May 25 '16 at 15:49
  • \$\begingroup\$ @JoshPetrie I completely agree, just wanted to point out this small caveat if you need to check a 'click' instead of a 'press'. :) \$\endgroup\$ – Roy T. May 26 '16 at 9:57
10
\$\begingroup\$

An alternative way (Josh's approach is great too!) would be to setup an boolean on SDL_KEYDOWN, and possibly also ignoring all repeated key events. That you can do by checking the repeat member of the key event.

Then you could implement your own timer, which doesn't have to be anything fancy, and implement key repetition your self. You could either trigger the action directly from the timer, or even generate an SDL_KEYDOWN event, and unify the solutions.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.