how to delay keyboard input

In my text menus I want to be able to simulate the keyboard repeat rate that windows does when typing. Here is what I have tried:

elapsedMiliseconds += gameTime.ElapsedGameTime.Milliseconds;

//update only once per 1/2 second

if (elapsedMiliseconds >= 50)

{

UpdateInput();

elapsedMiliseconds = 0;

}

The UpdateInput method just acts on whatever state the keyboard is in. The problem I'm having is that I completely miss / ignore some of the keystrokes by the player with the above code. Is there a more elegant way to do this

Without the above code it's too responsive and UpdateInput is called several times even if someone just taps a key.



Answer this question

how to delay keyboard input

  • USJOHN

    What you're talking about is Buffered Input. Basically you would want to collect every input that they give, and store the effect of it in a buffer of some sort. It could be as simple as creating a Queue<Keys> and every time a new key is pressed, add it to the queue. Then use your timer to handle the input; only instead of polling the keyboard for a new keypress, Dequeue your queue and handle that.

    Of course you'll have to make sure that you only add NEW keypresses to the queue. That's pretty simple; just keep a copy of your previous KeyboardState and compare the keypress to the previous version.

    What you're describing there is exactly the method I use to slow down stated inputs like the XBox 360 controller's d-pad for menu selection. In that case you only want to sample the input once every few milliseconds or the input goes too quickly



  • kiwilamb

    The other thing you can do, is make your Keyboard class support event-based actions. Using the code provided in the XNA MSDN Help, you can wrap over it, and check for events like keyup or keydown which can be declared as actual events in the class. And whenever you update, you can just raise those events. And it'll only register once, so the keyboard delay thing wouldn't be such a big problem.
  • Ron L

    Instead of doing the timing outside, do it inside. Here's some basic code (could probably be better structured) to give you an idea of how it could work. Basically just reset whatever timer to the default value whenever no button is pressed.


    elapsedMilliseconds -= gameTime.ElapsedGameTime.Milliseconds;

    if (Keyboard.GetState().IsKeyDown(Keys.Up) || Keyboard.GetState().IsKeyDown(Keys.Down))
    {
    if (elapsedMillseconds <= 0)
    {
    //do whatever you want
    elapsedMilliseconds = 50;
    }
    }
    else
    {
    //if we are here, no button is down so we can restart the timer to 0 so that the next button automatically works
    elapsedMilliseconds = 0;
    }

  • how to delay keyboard input