pygameのGUIフレームワーク(2)
Pygameのサイトに上がっているGUIフレームワークで目にとまったものをいくつか(OcempGUI,simple game gui, GooeyPy)見てみたが,OcempGUIのイベント・レイヤー管理がしっかりしているのでこれをベースにすることにした.ドキュメントとサンプルが充実しているのも嬉しい.
OcempGUI - pygame - python game development
ただし,サンプル画像を見て分かるとおり,ゲーム向けというよりはデスクトップアプリケーションで使うためのGUIという趣が強い.もちろん同じフレームワークでも画像を変えるだけで大きくイメージが変わってくるから一概には言えないが,OcempGUIの場合はソースを見てもやはりゲーム向けという感じはしなかった.
ゲーム向きじゃないと思ったのは下の二点.
dirty rectを使った描画回数の節約
前のフレームで変更があった部分だけ再描画するという手法.画面の描画というもっともコストの大きい処理を減らすことで高速化を図るモノだが,頻繁に画面の更新が行われるゲーム*1ではあまり効果が無く,処理を書く方も少し面倒になるので使われないと聞く.
逆に,デスクトップアプリケーションは基本的にユーザの行動が無ければ画面が変更されることもなく,しかも大事なのは画面のエフェクトではなくそのアプリケーションが行う処理なのでdirty rectを使うのは理にかなっている.
画面更新時は親widgetのみ描画
widgetってのはボタンとかウィンドウといったいわゆるコントロールのことで,ウィンドウのようにさらに内部にボタンなどを配置できるモノを親widget,中に配置されるものを子widgetと呼んでいる.surfaceは画面に描画する画像のこと.
親widgetと子widgetは親が下で子が上に乗っているという位置関係になっている.親と子はそれぞれ自分の描画するべきsurfaceを持っているのだが,それぞれが画面に描画しようとすると重なっている部分でどうせ親の背景は隠れてしまい,描画のコストが無駄になってしまう.なので,あらかじめ子widgetの画面を親widgetのsurfaceに転写して,画面更新時に描画するのは親widgetの画面だけにしている.
これと先ほどのdirty rectの組み合わせでさらに描画回数が減るんだけど,例えば親widgetを半透明にして子widgetはくっきり表示させるといった細かい処理が難しくなる.
なのでここらへんの描画周りを書き直して,あとは自分で使いやすいようなライブラリを書いてみる予定.
スタイルを指定するリソースファイル
widgetを追加するときにソース上でごちゃごちゃとスタイル指定とかやりたくないので,yaml形式(jsonみたいなもの)のリソースファイルでほとんど指定できるようにする予定.
zipに対応した透過的なファイルシステム
通常のファイルシステムとzipファイルのようなアーカイブをシームレスに扱えるFileラッパを用意した.これはyaneSDKのアイデアをもらった.例えば"/test/data/main.py"というパスにアクセスしようとした場合に通常のパスで存在すればもちろんそれを読み込むが,それが無い場合は自動的に次のような形式のパスを探す.
/test/data.zip(main.py) # data.zipの中にmain.pyがある /test.zip(data/main.py) # test.zipの中にdata/main.pyがある
プログラム配布時に生のファイルがそのまま見れるのはちょっとかっこわるいのと,暗号化サポートとかしたい場合に使おう.暗号化まではやらないと思うけど.
タスクシステムとの統合
一フレームごとに何かしらの処理を行うタスクシステムと,クリックなどのユーザイベントが起きたときに何かするWindowシステムってかなり違うんだけど,Timerイベントを使えば両方の利点を活かしたより使いやすいものができそうな気がする.
XPathで一気にwidgetを取得・更新
前に京都のオープンソースカンファレンスで見たんだけど,WindowシステムをDOMに見立ててXPathを使い,画面上の複数のwidgetを取得したりといったことをやっていたのが面白そうだった.使わない可能性も大なので優先度は低い.
他のフレームワークを見てて「自分のやりたいこと・書きたいスタイル」と「フレームワークの可能性」のすりあわせがすごく難しいなと思った.フレームワークの推奨する書き方に対して自分の書こうとしているスタイルに自信が持てるなら自分専用のフレームワークにすればいい.自分のスタイルを既存のフレームワークの中で実現できるならそれを使えば良いが,それが無理・あるいは非効率ならば新たに自分で書けばいい.
しかし,フレームワークのソースを読んでもそのフレームワークに秘められたパワーに気づけてない可能性もある.そう考えると自分で書くことに少し不安を覚えるが,気づけないものは「もともと無かったんだ」と割り切って書いていくしかない.
*1:毎フレーム背景を動かすとか