mieki256's diary



2017/09/15(金) [n年前の日記]

#1 [pi3d][python][raspberrypi] pi3dでキー入力を取得

2Dのリアルタイムゲームを作りたいならキーボード入力の取得ぐらいはできないと話にならないだろう、と思えてきたので、pi3dでキー入力を取得する方法について少し調べたのだけど。これが…ちょっとなかなか厳しい気配が…。

フツーに取得。 :

pi3d_demos のサンプルを眺めながら、フツーに取得するソレを試してみたり。

get_keyboard1_ss.gif

_get_keyboard1.py
_airplane_01_64x64.png (CC0 License)
u"""
pi3d input keyboard sample.

キーボード入力を取得してみるサンプル。
WASDキーで上下左右に動かしてみる。
ESCキーで終了する。

Windows10 x64 + Python 2.7.12 32bit + pi3d 2.21
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import pi3d

# ウインドウ生成
display = pi3d.Display.create(w=640, h=480, frames_per_second=60)

# シェーダーを生成。uv_flatは照明関係の計算をしない。
shader = pi3d.Shader("uv_flat")

# カメラを平行投影に
camera = pi3d.Camera(is_3d=False)

# テクスチャを読み込み
tex = pi3d.Texture("airplane_01_64x64.png", mipmap=False)

# スプライトを生成
x, y, z = 0.0, 0.0, 20.0
spr = pi3d.ImageSprite(tex, shader, w=64, h=64, x=x, y=y, z=z)

# スプライトをDisplayに登録
display.add_sprites(spr)

# キーボード取得用クラスを生成
keys = pi3d.Keyboard()

# メインループ
while display.loop_running():
    spd = 8.0

    # キー入力で座標を変化させる
    k = keys.read()
    if k == ord("w"):
        spr.translateY(spd)  # スプライトのy座標を変化
    if k == ord("a"):
        spr.translateX(-spd)  # スプライトのx座標を変化
    if k == ord("s"):
        spr.translateY(-spd)
    if k == ord("d"):
        spr.translateX(spd)

    if k == 27:
        # ESCキーが押されたらループを抜けて終了
        keys.close()
        display.destroy()
        break

動いた。と思いきや、これはこれでかなり問題が。動きをよく見ると分かるけど…。キーを押すと、「タッ……タタタタタ」という感じの動きになってしまっている。

要するに、ブラウザやエディタ等で文字を打ち込む際に、キーのオートリピートが働いたりするけど、アレがそのまま入力されてる・取得されてしまっているわけで。

ゲームを作ろうとした場合、コレは非常にマズイ。インベーダーゲームですら、レバーを倒してから自機が「タッ……タタタタタ」なんて動いたりしないわけで。ということで、このやり方はマズイ。これじゃ使い物にならない。

TestEvents.pyが動かない。 :

_pi3dのFAQページ によると、 _pi3d_demos の TestEvents.py を実行するとキー入力やマウス入力、ジョイスティック入力を取得する様子を確認できるよ、と書いてある。

試してみたところ、Raspberry Pi Zero W 上では動作した。
  • キーを押した瞬間
  • キーを離した瞬間
  • オートリピートが働いてキー入力された瞬間
それぞれを取得できてる模様。

ところが、Windows上で実行するとエラーが出る。
> python TestEvents.py

Traceback (most recent call last):
  File "TestEvents.py", line 6, in <module>
    from pi3d.event.Event import InputEvents, code_to_key
  File "C:\Python\Python27\lib\site-packages\pi3d\event\Event.py", line 4, in <module>
    from pi3d.event import EventHandler
  File "C:\Python\Python27\lib\site-packages\pi3d\event\EventHandler.py", line 4, in <module>
    from pi3d.event.EventStream import EventStream
  File "C:\Python\Python27\lib\site-packages\pi3d\event\EventStream.py", line 1, in <module>
    import fcntl
ImportError: No module named fcntl

調べてみたところ、Windows版Pythonに、fcntl というモジュールは無いようで。fcntl は Linux版Pythonでしか使えないという…。

_python - fcntl substitute on Windows - Stack Overflow

上記フォーラムで、「fcntl.py というファイルを作って、中でこういう記述をすれば、とりあえずエラー回避はできるよ。機能としては一切働かないけどな」と書かれていたので試してみたのだけど。
> python TestEvents.py

Traceback (most recent call last):
  File "TestEvents.py", line 30, in <module>
    inputs = InputEvents( key_handler_func, mouse_handler_func, joystick_handler_func, syn_handler_func, unhandled_handler_func)
  File "C:\Python\Python27\lib\site-packages\pi3d\event\Event.py", line 70, in __init__
    keyboards =  find_devices("kbd")
  File "C:\Python\Python27\lib\site-packages\pi3d\event\FindDevices.py", line 179, in find_devices
    with open("/proc/bus/input/devices", "r") as filehandle:
IOError: [Errno 2] No such file or directory: '/proc/bus/input/devices'

「fcntlなんてモジュールはねえよ」と怒られなくなったものの。しかし今度は、「/proc/bus/input/devices なんてファイルもディレクトリもねえよ」と怒られるという。…うん。そのファイル、Linuxは持ってるけどWindowsが持ってるわけないんだよねえ…。

_epics/powermate-event - Epics Users JP

Linuxに接続された入力デバイスの状態は、そこで提示されるという仕組みで…。Windowsにはそんなの無いんだよ…。

ということで、Windows上でも動くようにと考えると、TestEvents.py のソレではダメっぽいなと。

pi3d.Keyboard.PygameKeyboardをどうにかできれば。 :

_pi3d/Keyboard.py を眺めた感じでは、Windows上でpi3dを動かした場合、pi3d.Keyboard() は pi3d.Keyboard.PygameKeyboard() を返すようで。ということは、pygame がキー入力をそれらしく取得できるなら、pi3d 上でもキー入力を取得できるように変更できそうな…。

しかしコレ、pi3d.Keyboard.PygameKeyboard() の read() を眺めていて気付いたけど、キーの同時押しを取得できないのでは…。リストの一番最初の値しか取得してなくて、他のキー入力は全部捨ててるよな…。

以上です。

過去ログ表示

Prev - 2017/09 - Next
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project