kowさんは天ざる大好き

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

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

去人たちのアプリとは直接関係ないデモなどを移植して、無駄に忙しいkow@suhitoです。
忙しくても忙しくなくても更新速度はこんなものなので心配には及びません。


■yamalibディレクトリ
こちらがライブラリ候補のクラス群です。

■yamalib/Y4dConst.cs・yamalib/YamalibConst.cs
これはライブラリ共通で使う定数をまとめたクラス。
たとえば、Color4ubで白を表す rgba:255,255,255,255は定数にしたいと思いますよね。
毎回必要があるたびに new Color4bu(255,255,255,255)って書くのは面倒だし。
そんな風に定数を集めたクラス。
そんなことをいっても、不変クラスじゃないColor4buは書き換えのないことを限定で使わないといけませんが。

■yamalib/draw
これは描画に関するクラス群。
ある機能をもって描画するクラスがあります。
たとえば、ConbineTexture.csは複数のテクスチャを一枚にみえるように描画する。
5000 × 5000 px の巨大なテクスチャを描画したいとしたら、それを一枚の画像としてTextureとして読み込むのはよろしくないことがおこる。
OpenGL基本的に2の羃乗サイズじゃないとテクスチャにできない。つまり5000 × 5000pxの画像は 8192 × 8192pxに拡大してからテクスチャに登録することになる。
これはとてもばかばかしい。メモリの無駄遣いである。そこででかい画像を512×512サイズにスライスした画像を複数枚読み込んで一枚の5000 × 5000のテクスチャにみせかけるように実装しているクラスである。(ついでにいえば、このクラスは本来ITextureを実装しているべき)


NumberCounter.csは0〜9までの数字画像からカウンタ表示するクラス。
サイトで使用するアクセスカウンタなんかを想像してもらえればわかりやすいかもしれない。

TileTexture.csは、あるパターンから矩形のブロックを描画するクラス。
使用例をみてもらうのが早いだろう。
去人たちではダイアログボックスの実装にしようしている。
ダイアログボックスを描画するときに、縦横サイズは自由にかえたいと思うだろう。
長いメッセージをダイアログボックスに表示するなら、横サイズをのばさないといけないし、メッセージを列挙するなら縦にのばさないといけない。
ダイアログボックスを一枚の画像として用意しておくと、拡大縮小して対応することになるが、これだと縦横比がくずれてしまう。
さらに、拡大するとなると画像も劣化する。
だから、
 右上・上中・左上
 右中・中中・左中
 右下・中下・左下
のように、9枚の画像をよういして、必要なサイズに応じて、パターンを目的のサイズに繰り返し描画する。
このクラス、ソースをみると悪戦苦闘しているのがわかる。
このようなロジックは本当に基本的なプログラミング能力が如実に反映されますな...
がんばりましょう(>わたしが)

■yamalib/draw/effect
これは突発的な効果付き描画クラス群。
概ね汎用にかける不思議な固まりになっています。

主に、エンディングやデモなで使用しています。
つまり、効果描画です。フィルムノイズのようなゴミを描画(FilmNoise.cs)したり、テクスチャを分解してパーティクルみたいに描画(ScatteredTexture.cs
)したり、応用がきかないけど効果を描画するクラス。
DecorativeColck.csはあのいわくつきのデモの時計を描画しているクラスです。

CameraWork.csは、カメラワークのような描画を実現するために作りました。
複数の点を与えて、それをBスプラインで補完する。逐次その点を移動していき、その位置オフセットに元の画像を描画することで、なめらかに移動しているようみせかけるという仕組みです。
去人たちのエンディング最後で使用されています。

■yamalib/gui
このディレクトリにはGUIパーツ的なクラス群がおさまっています。

FocusableTextureButton/FocusableTextureGUI/FocusableTextureGUIControl
これはyanesdkGUIである、TextureButton/TextureGUI/TextureGUIControlの拡張である。
キー操作によって、ボタンにフォーカスをあてるという機能が追加になっています。
WindowsではTABキーでボタン、メニュー、インプットにフォーカスをあてることができますが、それと似たようなことをさせるための拡張です。
このクラスも試行錯誤の末できました。

そのほかに、リストボックス、スクロールバー(音楽試聴でのプレイリストで使用)、スライダー(オプションでのボリューム調整に使用)、ダイアログボックス(終了などのダイアログボックス)などがあります。

■yamalib/input
これは入力デバイスに関するクラス群です。
これらは少しトリッキーなクラスになっています。(ともすれば使いづらいともいう)


yanesdkにはマウスもキーもジョイスティックもあるのに、何を? と思うかもしれないが何をしているのか簡単に説明しよう。
まず、基本としてIMouseInputというインターフェースを導入している。
yanesdkのMouseInputクラスをそのままインターフェース抽出したような形になっている。
なぜインターフェースか?
これは、何もしないMouseInputが欲しいという動機によるものだ。
何もしないMouseInputを去人たちでは何に使用したかというと、「終了しますか?」ダイアログボックスを表示しているとき、シナリオ画面では右クリックしても文字を読み進めたりしたくないわけで、そのとき、さっと何もしないMouseInputに切り替える。すると、ダイアログボックス表示中だから、マウス入力は無視するみたいな処理を書くことなくスマートに入力を無視できる。
このほかにもこれが効いてくる場面があるのだけど、そういう目的でIMouseInputを導入している。

MousedKeyはキーボードをマウス操作のように見せかけるクラスである。
エンターキーはマウスの左クリック、エスケープキーはマウスの右クリックと同じような動きにみせるなどの用途に使用できる。
そのようにすることで、ボタンにフォーカスがあるときにエンターキーを押すことでマウスの左クリックと同じように選択することができる。


MultiMouseは複数のIMouseInputを一つにまとめて扱うことができるクラスだ。
実際にどのように使用しているかというと、前にあげたMousedKeyとMouseInputを一つにまとめて一つのマウスと見せかけている。
このように一つにまとめておくと、「左クリックされているか」と問い合わせれば、マウスの左がおされているか、または、キーボードのエンターキーがおされていれば「左クリックされた」とすることができるということになる。


■yamalib/math
数学関係は苦手なので、どっかからさらってきたロジックから簡易的にBスプライン補完クラスがある。
まあ、補完法はBスプラインがあれば十分である。

■yamalib/model
このディレクトにおさめられているクラスはちょっとしたデータクラスである。
というか、そうであるべきだった。

Character.csは単純にシナリオ画面で描画するキャラクターデータを保持するデータクラスの予定だったのだけど、ごてごてとしたクラスになっている。
去人たちではまんま、Characterクラスを使ってキャラクター描画している。
どちらかというとkyojinディレクトにあるべきかとも思う。

■yamalib/util
あると便利なユーティリティクラス群である。

Counter.csはyanesdk2ndからの移植で演算子オーバーロードが適当だったりするが、一応移植した。
RootCounter、RootCounterSなどは定番。内分カウンタもある。
FreeLineカウンタは独自に実装したのだけど、これも実用にはきちんと実装しないといけない。
このカウンタは任意の点をもとにして、非線形のカウンタを作るためのクラスである。たとえば、はじめはゆっくりで徐々に加速して終わりに近づくにつれて減速していくようなカウンタに使える。
UIではそのような移動をさせるとリッチな感じになるますよね。flashコンテンツのメニューとかではよくみる、なめらかなあんな動きをさせるために作りました。


■yamalib/yanesdkext
これのディレクトリにあるのはyanesdkのクラスを拡張したクラス。

■yamalib/yanesdkext/draw
yanesdk/drawを拡張したクラス。
SurfaceLoaderはTextureLoaderのSurface版。去人たちAeroでSurfaceでがりがり描画する必要があったので作りました。

TransBltterはyanesdk2ndにあったトランジッタの移植。それと、簡単なFadeBltを追加しています。
本当はユニバーサルトランジションがあればいいんだけど、OpenGLでは実直に実装できないので、去人たちではTransBltterのパターンからトランジションしています。

■yamalib/yanesdkext/Font
 SurfaceFontRepository.csはyanesdkのFontRepository.csのSurface版。これも去人たちAeroのために作りました。


■yamalib/yanesdkext/system
yanesdk/systemのクラスの拡張クラスです。

SDLFrameExはSDLFrameを拡張したものです。何を追加したかというと、マウスのホイールアップ、ホイールダウンイベントを処理するようにしました。
yanesdkのMouseInputはホイールアップダウンに対応していない。じゃあ、SDLでホイールアップダウンはどうやって取得するかというとSDL_Eventから取得する。んで、SDLのメッセージポンプを処理するSDLFrameクラスにマウスイベントを拾うようにしました。

TimestampLogWriter.csはyanesdkにあるLogWriterにタイムスタンプ付きログ出力機能を追加したクラス。
ログに時間があったほうがいいな、とおもってちょこっと作りました。
yanesdkのLogWriterはなかなか便利ですな〜



というわけで、ざっとクラスの概観を追ってきました。
次は、各画面にそってどんな処理をしているのかもうちょっと詳しく見ていきたいと思います。