はじめに
先日pygameを弄っていたら、なぜかctrlを押していないのに、押されていることになるという謎現象が発生しました。そこで原因を探っていたところ、Windowsのトラックパッドで拡大したり縮小する動きをすると、ctrlのフラグが立つことを発見しました。(謎)
確認方法
ゲームループのどこかに以下の三行をいれて、ctrlを押してみると、フラグが立っていることが分かります。同様にトラックパッドを弄ってみると、これまたフラグが立っていることが分かります(なぜ...?)。
mods = pygame.key.get_mods() # 修飾キーの状態を取得
ctrl = mods & pygame.KMOD_CTRL # mods & 64
print(ctrl)
get_pressed
の方はどうか気になったので、そちらも試してみました
if pygame.key.get_pressed()[pygame.K_LCTRL]:
print('ctrlが押されています')
やはりというべきか、こちらも押されている判定になっていました。
ということは......
KEYDOWNイベントとKEYUPイベントも確認してみたら、しっかりイベントが発生していました。ここまでがっつり判定されていると、ちょっと困る場面が出てきますね。例えばタイピングゲームで、正誤判定をする際に、キー入力をしていないタイミングでミスタイプが発生するなどが挙げられます。
対処法なさそう
キーボード由来なのかトラックパッド由来なのかを判別するため、MOUSEWHEELイベントを使ってみようと考えましたが、イベントの発生が、KEYDOWN、MOUSEWHEEL、KEYUPの順で発生しているようなので、うまく行きませんでした。また、MOUSEWHEELは指を動かしている間しかイベントとして扱われませんが、フラグ自体は指を動かさなくても有効になっているため、その点から考えても無理そうです。
pygameの裏で動いているSDLが原因なのか、OSからSDLにイベントが渡る時点で同一に扱われているのか、この辺りがどうなっているのかまでは筆者には分かりませんが、いずれにせよこの挙動自体をpygame側から対処できる感じではなさそうです。(MOUSEWHEELを検知したときにsys.exit
すると、プログラム終了後にctrlが押しっぱなしの状態になるので、おそらくOS側の問題だと思います。)
最後に
ここまで読んで下さりありがとうございました。完全な対処法を探すのは難しそうなので、必要がなければctrl自体を無視するのが一番いいかもしれません。