0
\$\begingroup\$

Here is my code that's part of the main game loop:

  // ResetKeyState stores currentKeyState in previousKeyState
  // and then clears currentKeyState
  engine.ResetKeyState();

  // Fill currentKeyState
  while (SDL_PollEvent(&e) != 0)
  {
     // Call input to notify
     engine.Input(e);
     if (e.type == SDL_QUIT)
        engine.Quit();
  }

  // Return control to programmer for implementation
 engine.EngineUpdate();     

  // Draw a pretty picture
  engine.EngineDraw();

and then to handle the input I have Input(e)

void Engine::Input(SDL_Event e)
{
   switch (e.type)
   {
   case SDL_KEYDOWN:
      KeyIsDown(e.key.keysym.sym);
      break;

   case SDL_KEYUP:
      KeyIsUp(e.key.keysym.sym);
      break;  

   default:
      break;
   }
}

KeyIsDown stores the boolean state in an array as a true value.

KeyIsUp stores a false value.

Then later, I thought I would be able to do this to get a single input.

if (IsCurrentKeyDown('a') && !IsPreviousKeyDown('a'))

IsCurrentKeyDown and IsPreviousKeyDown just get data from their arrays

bool currentKeyState[INPUT_SIZE];
bool previousKeyState[INPUT_SIZE];

This way if you've are currently pressing the key but the value hasn't yet been stored it takes input once.

IE: You press the key so currentKeyDown is true and previousKeyDown is false until next update where currentKey gets passed to previousKey and the statement is then false. It's how Monogame and XNA do it so I figured I'd implement it here.

But it didn't work. I put a break point with a hit counter on it and it would hit it more than once per press. What am I doing wrong?

\$\endgroup\$
  • \$\begingroup\$ The issue is a bit unclear: you get multiple events of SDL_KEYDOWN per frame? \$\endgroup\$ – Alexandre Vaillancourt Apr 12 '16 at 10:00
  • \$\begingroup\$ No I do not. But the (current && !previous) should not be running a second time. \$\endgroup\$ – Andrew Wilson Apr 12 '16 at 10:06
  • \$\begingroup\$ Typically, if (IsCurrentKeyDown('a') && !IsPreviousKeyDown('a')) type of code is used to detect stuff like 'the event just happened', in this case, has the key just went down. As @Tyyppi_77 points out, you'll need another key array to store the state as well. \$\endgroup\$ – Alexandre Vaillancourt Apr 12 '16 at 10:10
1
\$\begingroup\$

Your issue is that SDL sends keyboard events only when the state changes. So, if you move your current buffer to the previous buffer and then clear the current buffer, your keystate won't be correct on any of the frames after a key press. On the frame when the key was pressed, the current buffer should hold the value, but on frames after, there won't be a mark in the current buffer. Even the prevous buffer will lose it's value after a couple of frames.

\$\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.