Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » way to check for key held without keystate?

This thread is locked; no one can reply to it. rss feed Print
way to check for key held without keystate?
Murasame
Member #15,209
July 2013

I am attempting to create a game engine in C++ (using Allegro, of course), and support keyboard input. I want the engine to support as many platforms as possible. currently, I use events to read in key presses (as opposed to keyState), because it keeps the engine as optimized as possible as it does not need to check the keys until one is pressed. However, many things that deal with key presses are dependent on how long the key is held, which is where keyStates are useful.

Long story short, I want to be able to check to see what keys are held without keyState. my current idea was to create an array of booleans the size of the maximum number of keys, set to true if the keys are down, false if up, and update them via key pressed events (isKeyUp or isKeyDown). However, keyboards (and the buttons on them) vary by platform. I know that the keyboard drivers for each platform determine where each key is, but not how to utilize that. Any suggestions or code snippets are welcome.

Two additional things: one, I read that if you press or release a key while the program is in focus, if the program loses focus and then you release or press the key, the program will not know that you did so. the implications are that if you move until a key was up, and the game never realizes the key was up because it lost focus, well, you could keep moving, and anyone who has played a flash game where this occurs can account to its annoyance. Can anyone confirm or debunk this? if this is true, does anyone know of a solution?

two, I know that Windows supports a toggle keys trick, where pressing the key toggles between it being up or down. Any idea how I would incorporate this?

Vanneto
Member #8,643
May 2007

I would do it like this (pseudo-code):

#SelectExpand
1 2// before the loop 3double start; 4bool keyPressed[ALLEGRO_KEY_MAX]; 5 6// 7ALLEGRO_EVENT event; 8al_wait_for_event (queue, &event); 9 10if (event.type == ALLEGRO_EVENT_KEY_DOWN) 11{ 12 if (!keyPressed[event.keyboard.keycode]) { 13 start = al_get_time (); 14 keyPressed[event.keyboard.keycode] = true; 15 } 16 else { 17 // Key still being pressed down 18 double duration = al_get_time () - start; 19 } 20 21} 22else if (event.type == ALLEGRO_EVENT_KEY_UP) 23{ 24 if (keyPressed[event.keyboard.keycode]) { 25 double duration = al_get_time() - start; 26 keyPressed[event.keyboard.keycode] = false; 27 } 28}

You could have an array of double's and save the duration for each key.

In capitalist America bank robs you.

ph03nix
Member #15,028
April 2013
avatar

I think this is a simple straight forward way to do it:

In game loop:

for(int i=0; i!=ALLEGRO_KEY_MAX; ++i){
      if(keys[i]) keys[i]++;
}
al_wait_for_event(queue, &event);

if(event.type == ALLEGRO_EVENT_KEY_DOWN){
    keys[event.keyboard.keycode] = 1;
}else if (event.type == ALLEGRO_EVENT_KEY_UP){
    keys[event.keyboard.keycode] = 0;
}

keys is an array of integers with length ALLEGRO_KEY_MAX, and each element stores the number of iterations the key has been pressed for.

Edit: I can't confirm or deny if losing focus will prevent the key up event to be triggered, but if it is the case you can check the state of the keys with an OS specific function (GetKeyState for Windows) to see if that specific key is pressed or released. It may not be multiplatform, but it's just one function call so it's not a huge deal.

Murasame
Member #15,209
July 2013

thanks for the responses. A buddy suggested trying to use a struct that acts like a keyboard state in that it stores array of bools for up or down at current time, but updates via key events. it also takes a keyboard state to refocus itself whenever the program regains focus after losing it (it also acts as the initializer). it works in theory, but in practice, well, that is the source of my newest problem. here's the current link https://www.allegro.cc/forums/thread/612912

Go to: