[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [pygame] key press question



Robert Flemming wrote:

> Initially I had written my application to use the event queue since I wanted
> to make sure and not miss any key presses.  As things progressed I needed to
> be able to use "chording".  Since my main loop was pretty dull I decided to
> try and switch things over to use state checking.  The problem I found is that
> I'm getting repeating characters.  I tinkered with the set_repeat value, but
> that only seems to work when using the event queue.  Am I missing something
> obvious here or is that just the way things works?
> 
> Like I said originally I'd prefer to use the event queue, but I'm not sure how
> to go about handling the simultaneous key presses.  I looked at several of the
> projects hoping to find an example, but came up empty.  Any thoughts or samples
> to point me in the right direction (for either option) are appreciated.

State checking is definitely the way to go for using simultaneous
keypresses.  If you use the event queue and need "chording" as you call
it you'll just end up doing the same type of thing by yourself anyhow -
setting flags when certain keys or down so you can react to
combinations.  So it's easier to avoid the overhead of doing it
yourself.

You're right, set_repeat() works only with the event queue.  The reason
you get repeats is because your program is, well, too fast!  That is to
say, your main loop is executing faster than the time most people can
press a key.  Preesing a key is fast to us, but ages to a computer.

There are a few approaches to this.  One is to simply ignore it.  This
usually works in action games where it doesn't matter if the player
moves an extra pixel or two or fires an extra shot.  From your
description this sounds undesirable.

Another idea is to delay after processing a keypress, to give the key
time to "spring back".  This is how I did it in PyRunner
(http://members.shaw.ca/paulsid/pyrunner/).  However, this is usually
not a good idea, and it only works in programs that don't tax the CPU
since they need to have time to absorb the delay without lowering the
frame rate to something terrible.  This is likely something that's not a
game.  It is certainly super-easy to implement; that's why I did it in
PyRunner.

Another solution is to only process the keyboard at regular intervals. 
This requires a precise timing mechanism, so it's quite touchy.  You'll
probably want to do this 5-30 times a second, depending on your program
and the way you use keys.  If you've got a timing mechanism to keep the
frame rate constant you can likely just use that, otherwise you'll have
to build a new one.  (In C you could augment this to avoid missing keys
by polling more often than processing and ORing the buffer with a saved
buffer each time, but this is probably impractical in Python.)

Lastly, you could have a timer or counter for each key that you set once
you process it.  Then you don't process it again until the timer/counter
gets to 0.  This is touchy as well but it does have the advantage of
letting you vary the delay.  So you could let a "fire" key repeat often
while restricting movement to a few times a second.

In the end some variation on one of the last two solutions is probably
best, but exactly what depends on how your program is using the keyboard
and what your priorities are.

Have fun...

-- 
======================================================================
Paul Sidorsky                                          Calgary, Canada
paulsid@shaw.ca                        http://members.shaw.ca/paulsid/
____________________________________
pygame mailing list
pygame-users@seul.org
http://pygame.seul.org