Before I start working with real-time sprite movement and timers, I decided to try something turn-based. So I programmed a simple set of functions to draw ASCII characters to the screen and am building a roguelike engine. But the main problem I keep running into is getting keyboard input. I can collect it just fine, the problem is that it's collected way too fast. Even tapping the key as lightly as possible detects two events at once! Is there a simple way to delay detection of key events?
Current game loop (The Draw functions near the bottom blit ASCII characters to the screen):
It's not your fault, but I'm so tired of seeing people struggle with getting key input. Allegro 4 should have higher level input functions. You're welcome to use my keyboard_handler.
It's use is simple. Call SetupKeyHandler() near the beginning of your program. In your logic loop, call UpdateKeyHandler(time_passed), and then use :
if (key_press(KEY_DOWN)) { do_stuff(); }
It also has support for key release, key holds, keys open, key double clicks, and key_held_for(duration) as well as extending allegro's key codes to support various combinations of SHIFT, CTRL, and ALT.
[EDIT]
Didn't see that the OP was using Allegro 5.
Looks great! Where is KEY_MAX defined, though? I keep getting undefined errors.
You confused me. Without scrolling down to see the rest of your code I thought you were using Allegro 4 because you are checking if (key[KEY_DOWN]) {/*...*/}. Now that I look further down, you are using Allegro 5 and are trying to emulate A4 with it. My keyboard_handler is for Allegro 4 only at this point.
So now, my advice is to drop use of your key array, and simply use the key press and release events that Allegro 5 provides for you. Ie... move the code for if (key[KEY_*]) {DoStuff();} into
else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) { switch(ev.keyboard.keycode) { case ALLEGRO_KEY_UP: // key[KEY_UP] = true;DoStuff();break;
The problem is that an entry from your key array will be true for several logic loops at a time. It takes at least a certain amount of time between key press and key release.
Someone really needs to update that input tutorial if it's using jury-rigged code like that. It works much better now. One more question: what about key holds, double-taps, etc.? Is there a separate event for that or will I just have to make them myself?
Someone really needs to update that input tutorial if it's using jury-rigged code like that.
What input tutorial? What's the link to it?
One more question: what about key holds, double-taps, etc.? Is there a separate event for that or will I just have to make them myself?
There aren't any separate events for those, you'll have to track the state yourself. If you got a key down event, but haven't received a key up event then you have a key hold. For double clicks, you'll have to track the time of the last key down event and compare it to the time of the new key down event that matches it.
Anyway, thanks for the help! Keyboard input is a lot easier than it seemed with that odd emulation of Allegro 4 the tutorial was trying to pull off.
Someone really needs to update that input tutorial if it's using jury-rigged code like that.
The code there is really only for really basic input needs. Something that only needs to know if a key is pressed at any given time. Trying to show something more complex would probably just confuse things more.
I'm open to a second Keyboard tutorial showing more advanced concepts though.
Yes, it's odd that the Allegro 5 Input Tutorial uses a key array instead of checking the key state with the Allegro 5 functions al_get_keyboard_state and al_key_down.
Yes, it's odd that the Allegro 5 Input Tutorial uses a key array instead of checking the key state with the Allegro 5 functions al_get_keyboard_state and al_key_down.
Not really. The keystate stuff is a dirty hack, imo worse than storing your own key array. Also its far less efficient. The tutorial only stores keys it needs, where as the keystate stuff stores all of them regardless. and copies them...