KeyListener Why?

I know this topic has been talked about over and over again, but as a newbee i don’t yet get it.

Most example games i’ve seen use a KeyListener when detecting a pressed key and set a boolean variable like downArrow or k_button. Later some method do something like “if (downArrow) positionY += 1;” The question is why can’t we do this simple thing right when we detect the keypress?? Why all these booleans?? I can understand if there is a lot code for a keystroke that you want to move that block of code to another place making i cleaner. But for the example above it would only make it less readable. Also if you got several Threads running i can understand it, but for single threaded apps?

What am i missing? PLEASE. =)

One reason is that you are supposed to do as little as possible inside a listener method. These methods are called from the event dispatch thread. The more time you spend in them, the longer other events have to wait. Since all painting is called from this thread, you really don’t want to hang it up.

If you’re using AWT there’s no such thing as a single threaded app, since AWT runs a whole bunch of stuff in the background.

The size of the method isn’t really the issue, since just adding one to a position really isn’t any more hassle than setting a boolean.

The point is that you want the whole update process to be synchronised with your rendering. Since Events arrive on a seperate thread they can happen at any point during your rendering cycle. If for instance your main character was built up of say 5 sprites (maybe a tank with multiple guns?), you’ve drawn the first 3 then the event comes in. You update your players position straight away causing the next 2 sprites to be draw in a different position.

It only gets worse when you consider player position as a factor of scrolling where the whole screen can get out of sync half way through the rendering loop.

As always the ideal is to stick to a single thread, if you’re using AWT to detect events the only way you can keep the truly single thread model is to control when your updates are performed based on the booleans.

Obviously there are other solutions to this, synchronising your rendering loop against event loops but this tends to lead to performance impact and unresponsive inputs.

The added benefit is that different platforms handle key repeat in different manners, using the booleans prevents this having any impact on your updates.

Hope this helps,

Kev

The thing is… if you press a key… an event is fired… ok.

If you release a key… an event is fired… ok.

But in between… well there can be something like no event for half a second and then some event hammering. How should your game handle that?

Well, of course… “not at all” is the easiest option, which means just using flags :wink:

Thanks for all replies! I think i get the picture now…
:smiley:

Just to be sure, the KeyListener is only called once when you first press a key, and once when you release the key (disregarding key repeats for the moment because you don’t want to rely on that in a game). Your game is probably running more frames in between the keypress and keyrelease events and you probably want your character to keep moving during that time. It’s the difference between bashing your left button over and over again to move the player left, and pressing and holding the left button just once until you release it; or the difference between RSI after one game or after a thousend games :wink:

[quote]Just to be sure, the KeyListener is only called once when you first press a key, and once when you release the key (disregarding key repeats for the moment because you don’t want to rely on that in a game). Your game is probably running more frames in between the keypress and keyrelease events and you probably want your character to keep moving during that time. It’s the difference between bashing your left button over and over again to move the player left, and pressing and holding the left button just once until you release it; or the difference between RSI after one game or after a thousend games :wink:
[/quote]
Actually, if you press and hold down a key, many key press events continue to fire. That’s why flagging is even more relevant, since for example someone may only intend only 1 movement space per press and release instead of every press. There just isn’t a 1:1 ratio of press:release.

Being a computer programmer, RSI is probably a forgone conclusion anyways. :wink:

It’s easier to use a Set object to store all the currently pressed keys, and then cycle through them during a game ‘tick’. A set will store only one instance of each key, so you won’t get duplicates… and that way it avoids creating lots of unnecessary booleans. You can use mySet.add(keyValue) on the keyPressed event, and mySet.remove(keyValue) on keyReleased. To cycle through them you can just get mySet.interator(), and make a simple while(iterator.hasNext()) loop. It’s as simple as that.

keeping in mind that iterators will throw you an exception whenever the contents of the list they are iterating is changed, so you still have to be careful of asynchronous stuff going on here…

Umm…i agree with all above, but i think that u missed one important thing(or maybe i missed it cos my eyes are sleepy)-
This boolean array allows us to detect multiple key presses. If the code would just have in
public void keyPressed(Keyevent ke){
if(somekey)do something
if(otherkey) do something

then our code would only detect last of them i think. But if we set a flag, then we can know if they are both pressed simultaniously.

Na, if you got multiple key presses you’d get multiple KeyEvents fired and hence keyPressed would be called multiple times allowing you to detect them.

Kev