2017/09/17(日) [n年前の日記]
#1 [pi3d][python][raspberrypi] pi3dのキーボード入力はちょっと使い物にならないかも
pi3d のキーボード入力について調べてるのだけど。
コレ、ゲームを作るには機能が足りなくて、使い物にならない気配。他モジュールと組み合わせてどうにかできないかとググっているけど、解決策が見つからない…。
Windows + pi3d、あるいは、Linux + pi3d なら、pygame と併用すればなんとかなると分ったけど。Raspberry Pi + pi3d の場合、解決策が見つからなくて…。
コレ、ゲームを作るには機能が足りなくて、使い物にならない気配。他モジュールと組み合わせてどうにかできないかとググっているけど、解決策が見つからない…。
Windows + pi3d、あるいは、Linux + pi3d なら、pygame と併用すればなんとかなると分ったけど。Raspberry Pi + pi3d の場合、解決策が見つからなくて…。
◎ 問題点。 :
Raspberry Pi + pi3d の場合、pi3d はキーボード入力を調べるために curses を使うので、以下の問題があって。
この2点がどうして問題になるのか、図で描けば分かるだろうか…。
例えばだけど、カーソルキーの上と右を同時に押したら自機が斜めに移動する、という処理ができない。二つのキーが同時に押されてることを判別できないから。これではレトロ風の2Dスクロールシューティングゲームすら作れない。
また、「キーが押された瞬間」しか取得できないのも厳しい。一応、オートリピートがかかるから、連続して動いてるような「気分だけ」は得られるけど、最初の1回目に反応した直後、ピタッと止まるのが厳しい。これではインベーダーゲームやパックマンすら満足に作れない。また、各環境のオートリピート設定によって、それぞれ移動速度が異なってしまう可能性もある。
いやまあ、一応、「キーが押された瞬間だけ取得できる」という仕様でも、どうにかできないこともないけれど。動きを止めるためのキーを別途用意しておいて…例えばテンキーの5を押すと動きが止まるとかってお前は _FM-7 か! 21世紀にもなってFM-7ライクな操作仕様はないだろう…。
pi3d というライブラリ・モジュールは、あくまで、OpenGL ES を使って3Dモデルを簡単に描画できますよ、というモジュールなのだろうなと。それ以外の使われ方を想定していない気がする。少なくとも、リアルタイムゲームの類をコレで作れるかも、てなことは考えてないのではないかなあ。だって、あり得ない。キーボード入力周りの、こんな仕様。あり得ないよ。
- 押されているキーを1つしか調べられない。複数キーが同時に押されてることを判別できない。
- 何のキーが押されたか、という情報しか得られない。キーが離された瞬間を得ることはできない。
この2点がどうして問題になるのか、図で描けば分かるだろうか…。
例えばだけど、カーソルキーの上と右を同時に押したら自機が斜めに移動する、という処理ができない。二つのキーが同時に押されてることを判別できないから。これではレトロ風の2Dスクロールシューティングゲームすら作れない。
また、「キーが押された瞬間」しか取得できないのも厳しい。一応、オートリピートがかかるから、連続して動いてるような「気分だけ」は得られるけど、最初の1回目に反応した直後、ピタッと止まるのが厳しい。これではインベーダーゲームやパックマンすら満足に作れない。また、各環境のオートリピート設定によって、それぞれ移動速度が異なってしまう可能性もある。
いやまあ、一応、「キーが押された瞬間だけ取得できる」という仕様でも、どうにかできないこともないけれど。動きを止めるためのキーを別途用意しておいて…例えばテンキーの5を押すと動きが止まるとかってお前は _FM-7 か! 21世紀にもなってFM-7ライクな操作仕様はないだろう…。
pi3d というライブラリ・モジュールは、あくまで、OpenGL ES を使って3Dモデルを簡単に描画できますよ、というモジュールなのだろうなと。それ以外の使われ方を想定していない気がする。少なくとも、リアルタイムゲームの類をコレで作れるかも、てなことは考えてないのではないかなあ。だって、あり得ない。キーボード入力周りの、こんな仕様。あり得ないよ。
◎ Raspberry Pi専用スクリプトにすればどうにかできるのかも。 :
_pi3d.event.Event
の動作サンプルスクリプト、
_pi3d_demos/TestEvents.py
を Raspberry Pi上で実行すると、
ただ、そのやり方は、Windows や Linux では使えないので…。
でもまあ、考えてみれば、そもそも OpenGL が使える環境なら ―― Windows も Linux も Raspberry Pi2/3 も OpenGL を使えるのだから、それらの環境では PyOpenGL だの pyglet だのを使ってこの手のソレを書けばいいわけで、あえて pi3d を使わなくても、という気がしてくるし。
Raspberry Pi1 や Zeroシリーズはメモリが少なくて OpenGL を使えないから、代わりに OpenGL ES を使う pi3d はどうでしょうか、という話なわけで、だったら、pi3d を使うってことは、Raspberry Pi専用スクリプトとして書いちゃって問題ない場面じゃねえの、と割り切ってしまうのもアリかもなと。
これがもし、Pi1/Zero/Zero W でも OpenGL が動いてくれるなら話が簡単になるのだけど…。そこは難しい事情があるのだろうな…。
- キーを押した瞬間
- キーのオートリピートが働いてキー入力がされた瞬間
- キーが離された瞬間
ただ、そのやり方は、Windows や Linux では使えないので…。
- Windows と Linux は pygame を併用する処理を、
- Raspberry Pi は pi3d.event.Event を使った処理を、
でもまあ、考えてみれば、そもそも OpenGL が使える環境なら ―― Windows も Linux も Raspberry Pi2/3 も OpenGL を使えるのだから、それらの環境では PyOpenGL だの pyglet だのを使ってこの手のソレを書けばいいわけで、あえて pi3d を使わなくても、という気がしてくるし。
Raspberry Pi1 や Zeroシリーズはメモリが少なくて OpenGL を使えないから、代わりに OpenGL ES を使う pi3d はどうでしょうか、という話なわけで、だったら、pi3d を使うってことは、Raspberry Pi専用スクリプトとして書いちゃって問題ない場面じゃねえの、と割り切ってしまうのもアリかもなと。
これがもし、Pi1/Zero/Zero W でも OpenGL が動いてくれるなら話が簡単になるのだけど…。そこは難しい事情があるのだろうな…。
◎ pygameウインドウの上にOpenGL ESを乗せるわけにはいかんのだろうか。 :
Raspberry Pi用の Minecraftは、フツーのウインドウを表示したその上に、OpenGL ES のレイヤーを位置合わせして配置して描画をしてるらしいけど。
pi3d も、似たようなことができないのだろうか。pygameのウインドウを生成して、そのpygameウインドウの位置に OpenGL ES のレイヤーを置いてソレらしく見せるとか。それができれば、Windows、Linux、Raspberry Piで共通して動かせるスクリプトを書けそうだけど…。描画以外は、pygame の機能をそのまま使えばいいわけだし…。
考えが甘いかな。かもしれん。何か罠が潜んでそう。
ちなみに、Raspberry Piの描画関係については、以下のやり取りで紹介されてる画像が分かりやすかった。フツーのLinuxのデスクトップは X.Org と GLX が繋がってるけど、raspbian は X.Org と EGL が繋がってないからウインドウの移動に OpenGL ES が追従してこないのだ、等が説明されてる。
_Graphics Acronyms & What works with what? - Raspberry Pi Forums
pi3d も、似たようなことができないのだろうか。pygameのウインドウを生成して、そのpygameウインドウの位置に OpenGL ES のレイヤーを置いてソレらしく見せるとか。それができれば、Windows、Linux、Raspberry Piで共通して動かせるスクリプトを書けそうだけど…。描画以外は、pygame の機能をそのまま使えばいいわけだし…。
考えが甘いかな。かもしれん。何か罠が潜んでそう。
ちなみに、Raspberry Piの描画関係については、以下のやり取りで紹介されてる画像が分かりやすかった。フツーのLinuxのデスクトップは X.Org と GLX が繋がってるけど、raspbian は X.Org と EGL が繋がってないからウインドウの移動に OpenGL ES が追従してこないのだ、等が説明されてる。
_Graphics Acronyms & What works with what? - Raspberry Pi Forums
[ ツッコむ ]
以上です。