kowさんは天ざる大好き

創作に絶望すると、世界が反転した日記

Yanesdk.netによるノベルゲーム実装(6)

簡単なシーンタスクをみてみる。
kyojin/task/LogoTask.cs
一枚の画像がフェードイン表示したあと、フェードアウトさせつつもう一枚別の画像をフェードインさせる。
これをとても原始的な方法で実装している。

毎回Taskメソッドが呼ばれるわけだが、その中でOnMoveとOnPaintという二つの処理を行っている。
OnMoveは移動などの処理を、OnPaintはその結果を描画するというメソッドである。
ゲームが30fpsだとして、描画が重くて処理オチしたらどうなるだろう。昔のシューティングではキャラがいっぱいで動きが遅くなったりしたものだが、本来はそうなってほしくはない。(シューティングなんかでは意図的に処理おちをいれたりするけど...)
30fpsで1フレームあたり、1ドット移動する物体は1秒後、30ドット移動しているのが望ましい。
そこで、移動+描画という大きな処理のうち、移動だけは必ずやって、処理がおっついていないときは描画をスキップするという解決方法がある。
yanesdk2ndでは明白にこのような実装が推奨されていたのだけど、yanesdk3rd以降はそのような切り分けは要求されていない。
去人たちは通常、各シーンタスクで移動処理と描画処理というように明示的に処理を分けている。yanesdk.netは描画は高速なのは間違いないのだけど、それは3Dに対応のグラフィックチップが前提であって、3D非対応のものも未だ存在する。そういう環境におけるささやかな救済処置になるかと考えたためだ。
ただし、yanesdk.netでは移動と描画を明示的に切り分けるようにはなっていない。たとえばTextureButtonはOnPaint()という一つのメソッドしかなく、これはボタンの内部処理+描画を行うメソッドである。そのため、このメソッドを呼ばないとボタンとしての動きも処理されない。もし、処理おちしているときにマウスクリックしたとしてもボタンの入力判定は行われない。これだと、激重の状態でうんともすんともいわなくなる可能性がある。(そのためFpsTimerでは4フレームに1回は必ず描画するようになっていたりするのだが)
結局、手前で移動処理と描画処理を切り分けたとしてもyanesdkのクラスの方が対応していないのだから、そんなことはしないほうがいいと思う。処理オチでスキップするときは、移動処理も描画処理もスキップすると決めてしまったほうが良さそうである。もし、1秒後に30ドット先にいなければならないのだったら、タイマーでもつかって移動距離を制御すればいいのだし。
去人たちではOnMoveとOnDrawというメソッドに切り分けて記述しているが、上記のような経緯であり、今となってはそんな必要なかったかもなあと思っているわけである。


ちなみに、このシーンタスクでは2枚の画像を使っているのだけどTextureLoaderもSmartTextureLoaderも使っていない。
もちろん、画像ファイル名が変更になる可能性があるならば、定義ファイルを作ってTextureLoaderで読み込んだ方がいい。コンパイルし直すよか、定義ファイルを書き換えたほうが手間が少ない。

あと、ITextureの具象クラスを生成するとき
m_imgK2c = YamalibConst.CreateTexture("img/logo/logo01.png");
みたいにしている。
これは下と全く同じことだ。
m_imgK2c = new GlTexture();
m_imgK2c.Load("img/logo/logo01.png");

めんどいので、まとめたYamalibConst.CreateTexture()メソッドを作ったというのもあるけれど、
ITextureが何で実装されているかは、気にしたくないからである。とりあえず、ここでは GlTexture ということにしているだけだ。
yanesdk.netがDirectX対応に対応したらDirectxTextureクラスができるかもしれないし、もし、やっぱそっちのクラスにするとなったら、YamalibConst.CreateTexture()の中で、GlTextureをDirectxTextureに変更すればいいのである。