キャラ管理ライブラリを考える(2)

Actorクラスを上位に作って、それを継承してキャラクラスを作るのは最低限どうしようもない。
そのおかげでゲーム上のオブジェクトに対する操作はそのクラスに閉じるわけだし、どのみちそれなりの規模のゲームを作るならそういうものは作る必要があるだろう。
そこを簡略化するのがフレームワークの存在意義だから、それはそれでよい。


Actorクラスのオブジェクトをまとめて保持するのがレイヤだ。
レイヤは、例えば敵や、敵の弾や、自分の弾など、種類ごとに別に作り、Actorオブジェクトをまとめて保持する。
んで、レイヤ単位に処理順・描画順を決めて、管理下のオブジェクトをまとめて処理する。レイヤ内の順番は登録順だが、それを意識するようなものならレイヤを分けるべきだ。
レイヤをオブジェクトとして作ると、そのレイヤオブジェクトを保持する何かが必要になり、どうやってアクセスするかという問題が発生する。
具体的には、例えば敵オブジェクトが弾を生成しようとした場合、グローバルスコープから辿れるところに敵の弾レイヤオブジェクトがないと登録できない。
これを解決するには、
(a)グローバル変数$sceneに現在のシーンオブジェクトを入れて、シーンにはレイヤ配列を持たせてattr_readerする
(b)レイヤオブジェクトをグローバルスコープの定数に突っ込む
(c)キャラオブジェクトに自分が属するレイヤを教えておく
といった方法を取ることになる。


(a)は、配列にすると添え字でのアクセスになることが問題になる。番号管理は望ましくない。
(b)はサンプルシューティングが使っている方法で、定数というか、あれの場合はモジュールとしてManager=レイヤを作っているから、どこからでもアクセスできるようになっている。
モジュールとして作ると、レイヤごとにコードをまるまる書かないといけなくて、あまり嬉しくない。
(c)はオブジェクトに教えるというか、敵の弾だったら敵の弾クラスを作って、各々の弾はそこから派生するようにしておいて、敵の弾クラスのクラス変数に敵の弾レイヤを持たせるような感じか。
そういうのを理解できている人にはいいかもしれないが、俺的な感覚ではこれは難しすぎるから却下だ。


結局のところ、配列などでレイヤを管理できるようにしようと思うとアクセス方法は番号になり、オブジェクトを直接参照しようと思うとグローバル変数か定数になるということだ。
使い方から考えると、Layer.newしてグローバルの定数に突っ込んでおいて、それをシーンが持つ配列に登録するという形、すなわち(a)と(b)のハイブリッドが最も柔軟で簡単だろう。
サンプルシューティングもモジュールを配列に突っ込んで処理してるから、結局それと同じといえば同じだ。
ただ、グローバル変数や定数にレイヤを入れて扱うのを必須にするとか、推奨の使い方とするのは、なんだかちょっと微妙だ。
本来なら$sceneから辿るのがスジなのであって、グローバルスコープにレイヤを置くのは設計思想的には邪道だ。
まあ、シーンオブジェクトから辿れるようにしておいて、あとの使い方は自由というのがよいのだろう。


レイヤの機能としては、管理下のオブジェクトの移動・描画メソッドの呼び出し及び、衝突判定用データの管理と外への公開。
移動や描画そのものはキャラオブジェクトのほうでやることだから、レイヤ自身は特に難しい機能は無くていい。
これはほぼサンプルシューティングのモジュールの機能と同じ。
大きく違うのはこのあたりじゃなくて、Actorクラスによる移動・描画の自動化とシーン管理の追加だから、問題はない。
ってことは、まだ何も考えてないに等しいとも言えるわけだ。