Understanding Keyboard State

Debouncing Key Presses in SDL

What is the best way to debounce key presses in SDL?

Abstract art representing computer programming

Debouncing key presses involves ensuring that a single key press is registered only once, even if the key is held down for a longer duration.

This is particularly useful for preventing multiple triggers of a single action due to rapid key events.

Methods for Debouncing Key Presses

  1. Timing-Based Debounce: Use a timer to track the last time a key event was processed.
  2. State-Based Debounce: Track the state of keys and only process a key event when the state changes.

Timing-Based Debounce Example

Here’s an example using a timing-based approach to debounce key presses:

#include <SDL.h>
#include <iostream>
#include <chrono>
using namespace std::chrono;

class Window {
public:
  Window() {
    SDL_Init(SDL_INIT_VIDEO);
    SDLWindow = SDL_CreateWindow(
      "Debounce Key Presses",
      SDL_WINDOWPOS_CENTERED,
      SDL_WINDOWPOS_CENTERED,
      640, 480, SDL_WINDOW_SHOWN
    );
  }

  ~Window() {
    SDL_DestroyWindow(SDLWindow);
    SDL_Quit();
  }

  void HandleKeyboard() {
    const Uint8* state = SDL_GetKeyboardState(NULL);
    auto now = high_resolution_clock::now();
    auto elapsed = duration_cast<milliseconds>(
      now - lastPressTime).count();

    if (state[SDL_SCANCODE_SPACE]
      && elapsed > debounceDelay) {
      std::cout << "Space key pressed\n";
      lastPressTime = now;
    }
  }

private:
  SDL_Window* SDLWindow{nullptr};
  high_resolution_clock::time_point lastPressTime{};
  const int debounceDelay{200}; // 200 milliseconds
};

int main(int argc, char* argv[]) {
  Window GameWindow;
  bool running = true;
  SDL_Event event;

  while (running) {
    while (SDL_PollEvent(&event)) {
      if (event.type == SDL_QUIT) {
        running = false;
      }
    }
    GameWindow.HandleKeyboard();
    // Rendering code here
  }

  return 0;
}
Space key pressed

State-Based Debounce Example

Here’s an example using a state-based approach:

#include <SDL.h>
#include <iostream>

class Window {
public:
  Window() {
    SDL_Init(SDL_INIT_VIDEO);
    SDLWindow = SDL_CreateWindow(
      "State-Based Debounce",
      SDL_WINDOWPOS_CENTERED,
      SDL_WINDOWPOS_CENTERED,
      640, 480, SDL_WINDOW_SHOWN
    );
    std::memset(prevState, 0, sizeof(prevState)); 
  }

  ~Window() {
    SDL_DestroyWindow(SDLWindow);
    SDL_Quit();
  }

  void HandleKeyboard() {
    const Uint8* state = SDL_GetKeyboardState(NULL);
    if (state[SDL_SCANCODE_SPACE]
      && !prevState[SDL_SCANCODE_SPACE]) {
      std::cout << "Space key pressed\n";
    }
    std::memcpy(
      prevState, state, sizeof(prevState)); 
  }

private:
  SDL_Window* SDLWindow{nullptr};
  Uint8 prevState[SDL_NUM_SCANCODES]; 
};

int main(int argc, char* argv[]) {
  Window GameWindow;
  bool running = true;
  SDL_Event event;

  while (running) {
    while (SDL_PollEvent(&event)) {
      if (event.type == SDL_QUIT) {
        running = false;
      }
    }
    GameWindow.HandleKeyboard();
    // Rendering code here
  }

  return 0;
}
Space key pressed

Conclusion

Debouncing key presses in SDL can be achieved through timing-based or state-based methods.

The timing-based method uses a timer to ensure a key press is registered only after a certain delay, while the state-based method checks the state transition of the key.

Both methods are effective, and the choice depends on the specific requirements of your application.

This Question is from the Lesson:

Understanding Keyboard State

Learn how to detect and handle keyboard input in SDL2 using both event-driven and polling methods. This lesson covers obtaining and interpreting the keyboard state array.

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

Understanding Keyboard State

Learn how to detect and handle keyboard input in SDL2 using both event-driven and polling methods. This lesson covers obtaining and interpreting the keyboard state array.

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 36 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved