小浜治療院トップページ > 趣味に関して 目次 > Pygame その1
Pygame その1
Pygameをいじっていて、気づいたことがあるので書き留めておきます。
プログラムを組んで、いざ動かそうとすると、キー入力が速すぎて困りませんか?
1回押しただけなのに2つ以上反応する、みたいな。
キー入力の間隔が短い、間隔が速すぎる、等
解決策として提示されるのが
pygame.key.get_pressed()
と
pygame.event.get()
でキー入力を受け付けて、
その対処として pygame.key.set_repeat() をつかう。みたいな
以下のファイルを作ってみて、pygame.key.set_repeatの効果を確認してください。
import pygame
import sys
def main()
global tmr
pygame.init() #初期化
screen = pygame.display.set_mode((300,400)) #邪魔にならない控えめなウインドウ
clock = pygame.time.Clock()
tmr = 0
fps = 15 #毎秒のフレーム数
#pygame.key.set_repeat(1000, 20) #この効果を見る
while True:
tmr = tmr + 1
keys = pygame.key.get_pressed() #get_pressedで入力を監視している
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_LCTRL or event.type == pygame.K_RCTRL: #イベントハンドラで監視している
print(str(tmr))
if keys[pygame.K_SPACE] == 1: #get_pressedで入力を監視している
print(str(tmr))
pygame.display.update()
clock.tick(fps)
if __name__ == "__main__":
main()
まずはset_repeat()のところは#で無効化しておいてください。
とりあえず、実行すると(インデントがズレていたら、各自調節してください)スペースを押すか、CTRLキーを押すかでtmrが書き出されます。
get_pressed()の方、スペースキーは押している間ずっとtmrが書き出されます。
離すと止まります。
while True でループしている間、1周に1回get_pressedで監視しています。
なので、押している間、tmr が1周するごとに1反応します。
1周の周期はclock.tick(fps)で管理していますので、今回は1秒で15周、つまり15回押すことになります。
本人は短く押しているつもりでも2周に引っ掛かれば2回押したことになります。
KEYDOWNの方、CTRLキーはイベントハンドラで、1回押すと1回だけ反応します。
押しっぱなしでは連続入力を受け付けてくれません。
もう1回反応してもらうには、一度キーを放さなければならないのです。
では、set_repeat()の前の#を外して、set_repeat()の部分を有効にして実行してみましょう。
スペースキーの方は何の変化もありません。
押しっぱなしでも、短く押しても、get_pressed()は先ほどと変化なしです。
CTRLキーはどうでしょう。
短く押したら、先ほどと同じように1回しか反応しません。
しかし、押しっぱなしにしたら、連続入力を始めました。
これがpygame.key.set_repeat(1000, 20) の効果です。
pygame.key.set_repeat()はget.KEYDOWNのための関数です。
pygame.key.set_repeat()はget_pressedに影響を及ぼしません。
pygame.key.set_repeat(delay, interval)の1つ目の引数(delay)は最初の反応から2番目の反応までの待ち時間(ミリ秒)です。
pygame.key.set_repeat(delay, interval)の2つ目の引数(interval)は2番目の反応以降の待ち時間(ミリ秒)です。
なので、pygame.key.set_repeat(1000, 20)だと、
押しっぱなしにしたとき、1番目はすぐ反応します。1秒(1000ミリ秒)以上押しっぱなしにすると、2番目以降20ミリ秒間隔で反応します。
離したら最初の状態に戻ります。ということです。
これらはスペースキーを押したときは、tmrが1ずつ増加するのに対して、
ctrlキーの連続入力は同じtmrが何度も出てくる(ループ1周の内に何度も反応している)ことから分かります。
これらのことから、get_pressed()、 pygame.KEYDOWN 、key.set_repeat()をうまく使い分けてください。
残念ながら、2023年9月現在、get_pressed()で無駄な連続入力をスマートに回避する方法を私は知りません。
誰か教えて(涙)
皆さんの助けになれれば幸いです。