Hi,
I'm just making a litlle Tetris game using Allegro. You'll agree with me : it' easier to play with the keyboard
Thats how I tried to use the keyboard with my program ( apparently, it fail ) :
Firs of all, I installed the keyboard with : al_install_keyboard()
I initilize a "state pointer" : ALLEGRO_KEYBOARD_STATE *etat = NULL;
And I control if LEFT is pressed to output a sentence :
if (al_key_down(state,ALLEGRO_KEY_LEFT)){
cout << "GAUCHE";
}
But last one throw me an error message, telling me that I violate something T_T
Thanks for your future support !
Don't use ALLEGRO_KEYBOARD_STATE, use events. See this tutorial.
And completely aside from whether you use _STATE or events, you didn't initialize the state to anything useful, you just left it null...
When I started using Allegro 5, I used ALLEGRO_KEYBOARD_STATE like this:
ALLEGRO_KEYBOARD_STATE key_state; ... if (al_key_down(&key_state, ALLEGRO_KEY_LEFT)){ // Do something }
However, once you learn to use the new event system it is quite easy so I agree with SiegeLord, you should use events.
You must do this:
ALLEGRO_KEYBOARD_STATE state; al_get_keyboard_state(&state);
At that point, you can use the al_key_down function. You need to update (get) the state anytime you want to see if a key has changed, so you would need to call it at least once per logic loop.
See this tutorial.
Ouch. I think I like Fen/Matthew's idea better. I hope that's considered the standard method; trying to cobble together a rudimentary engine off this new API just now ...
Events have the advantage of not losing key strokes if you don't poll enough. Also, it's simple to build key state on top of events, but not the other way around.
The key state is more useful when you want to know if some key is currently held down. The events are more useful if you just want to know when a key was pressed. (e.g., Entering a name in a high score.)
In A4 terms, the events are more like keypressed with readkey, and the state is more like the key array.
I noticed that using the keystate, on Windows, if I hold shift, then minimize, let go, then restore, another call to a request to the keystate will yeild that shift is still pressed which it is not. Allegro should clear these or have away to clear them so that al_key_down() is reliable,
I noticed that using the keystate, on Windows, if I hold shift, then minimize, let go, then restore, another call to a request to the keystate will yeild that shift is still pressed which it is not. Allegro should clear these or have away to clear them so that al_key_down() is reliable,
Do you get a key up event in that case?
The question is more - should there be a key up event? For most games it probably would make sense to get a key-up event for any keys which are still pressed when focus is lost and a key-down event for any keys already pressed when focus is regained. On the other hand with the way each keyboard driver does their own state tracking currently it may not be easy to implement and technically it makes sense that you never receive a key-up for a key when it happens while you don't have keyboard focus.
Why can't Allegro 5 just refresh the key states when it regains focus? Allegro 4 did it. And by the way, I immensely prefer reading the key states as opposed to reading the key events. Why should I have to pass a key event to every object that listens for key presses when I could have them just check the global state instead? I mention this because I have an input library for A4 that checks the key states and produces key press/release/held/open states based on them.
Why should I have to pass a key event to every object that listens for key presses when I could have them just check the global state instead?
Because key state is inherently broken. For example if you press the keys left,left,right,left fast and read the key state in each game tick (marked with *):
* * * left left right left
Then your game will work as if you pressed left 3 times. For some games, this would not matter much. But for some it would mean they completely break (e.g. classic-style fighter where left,left,right,left might be some special attack combo). With events you never can miss anything.
Another example is a touchpad which implements touch-to-click as a mouse press and release at the same time when you first touch the pad. With events it's no problem, but with mouse state you will never catch the click as it's simply not long enough in a pressed state to ever catch it.
And there's many more examples where state will just mean your game is broken, especially when you consider that in some situation the game may slow down because some background process uses CPU or disk access. With events nothing is lost even if the game would skip for say, half a second. With state whatever happened in that half second is completely lost... and it could mean you die in the game whenever it stutters just for a bit.
The question is more - should there be a key up event?
One could argue either way on that, with the argument that if you don't you will think that keys that were once pressed are never released perhaps deciding in favour of saying that you should.
But my question was actually much more down-to-earth than that. Assuming the Windows port is the same as the OS X port, we simply pass along events that we receive from the operating system. If the OS never tells us that the key is no longer held down, then we need to do something special. If it does, there is a bug in the recording of the key state (I doubt that, if it's done the same as on OS X anyway, since the keyboard state should be updated as soon as the event is received, but worth checking anyway).
For what it's worth, the behaviour on OS X (with ex_keyboard_events) seems to be that a KEY_UP event is generated the next time the same key is pressed after we regain keyboard focus, which is also weird. Haven't looked into this.
Why can't Allegro 5 just refresh the key states when it regains focus?
Who says it can't? But the way it currently works is that Allegro keeps track of key up/down events for you. The keyboard state is updated incrementally.
The problem is actually not straightforward. When should Allegro send up/down events (and update the keyboard state)? Probably when the program re-gains focus. In that case you need to compare the keyboard states before and after the switch and then generate events that will make up the differences.
I immensely prefer reading the key states as opposed to reading the key events.
You are free to do that.
After getting used to it, I vastly prefer using the events rather than the state, mostly because with A4, I was converting that into up/down events anyway.
I mention this because I have an input library for A4 that checks the key states and produces key press/release/held/open states based on them.
So did I and it now updates them based on the keyboard event it gets passed. It really doesn't make that much of a difference and has the aesthetic advantage of only updating stuff when it knows that there is stuff to update (or we wouldn't have received a keyboard event in the first place). The rest of the time we can idle/sleep.
I personally do prefer the event system, but, most API's (or atleast WinAPI) provides weather or not CTRL, ALT, and Shift are pressed at the time of a mouse event, and in WinAPI it is always accurate. This is really the only reason I use the key states. It is because when I get mouse events I want to know about those 3 keys. Given this situation however, I will have to keep track of these myself.
The only flaw however, is that using this method rather than getting the key state is that if I return (regain Window focus) and shift is still pressed, it will now be unpressed until I get a key down with mouse again. For me that is the biggest problem. There should be a way for me to atleast accurately know the states at a given time so I can do this, and for shift to be set to pressed if it is when I regain focus. I know it is not easy, but I think some kind of solution should be found before AL5 release.
The only flaw however, is that using this method rather than getting the key state is that if I return (regain Window focus) and shift is still pressed, it will now be unpressed until I get a key down with mouse again.
Right; that's why the update should be done when keyboard focus is returned to the application, not when keyboard focus is lost. Probably.
Right; that's why the update should be done when keyboard focus is returned to the application, not when keyboard focus is lost. Probably.
Yes I completely agree, there's no sense in doing it when it is lost, but I do hope it is fixed.
Ok, thanks to all of you
PS : OMAGAD IT'S WORKIN'
:dance: :dance: :dance:
( Back to a more serious face )