pygame のキー入力取得は意外とクセがあるのかも?

キー入力の取得としては、主に

for event in pygame.event.get(KEYDOWN):
    if event.key == K_z:
        print "Key Z is pressed"

といった処理をする方法と、

pressed = pygame.key.get_pressed()
if pressed[K_z]:
    print "Key Z is pressed"

といった処理をする方法とが考えられるわけですが、それぞれ微妙なクセがあったみたいです。

pygame.event.get(KEYDOWN)

これを使う処理の場合 Keydown の発生タイミングが、なんだか微妙。例えば TENUKIS で↓キー押下時の落下・固定処理に KEYDOWN イベントを用いていたところ、↓を連打したときに、 K_DOWN の Keydown イベントが蓄積されたような感じになり、その後登場するミノが、手を離しても固定されてしまいました。
この場合の回避手段として、1回の落下・固定処理を終えたタイミングで pygame.event.clear() を呼び出したところ、この Keydown の蓄積的な現象は解消されました。

pygame.key.get_pressed()

これを使う処理の場合、必ずしも返ってくる配列が現状を反映していないようです。
解決策として、 get_pressed() を呼び出す直前で pygame.event.pump() を呼び出すようにしておくと、ちゃんと現状が反映されます*1。 したがって、上述のコードはこのように書くことに。

pygame.event.pump() #おまじない
pressed = pygame.key.get_pressed()
if pressed[K_z]:
    print "Key Z is pressed"

余談

TENUKIS では、左右の移動には pygame.key.get_pressed() を、回転には主に pygame.event.get(KEYDOWN) を用いるようにしました*2
get_pressed() で直ちに移動させるとコンコンができないので、数フレーム未満の get_pressed()[K_LEFT]==True では移動しないようにしています。

*1:via pygame.key — Pygame v1.9.5.dev0 documentation get_pressedのコメント欄を展開のこと。

*2:v0.3(未公開)