そういや私はゲーム製作してるんです。実はずっと相変わらずツールの方から攻めております。とりあえず今はタスクシステムの一つ上のレイヤーになるべくスプライト管理なるものを考えています。
●スプライト管理
・各描画される自機、自機の弾、敵などはスプライトという単位で管理を行う。
・スプライトには描画優先順位が持たされており、数値の小さいほど手前に表示されるようにする。
・スプライトにはその他、自発移動、左右上下端での自動反転、点滅、自動消滅などの自発的機能を盛り込む予定。
●実装
SortedList(※1)を使用する。
キーとしては優先順位(int)キー重複がダメだったので上位16ビットを優先順位下位16ビットを使いキーをユニーク化を検討、値はスプライト(参照値)になる。
要素の比較に用いるIComparerとして以下のようなものを使う
これによって優先順位の大きい順にソートされる。(優先順位大きい順に描画することで優先順位小さいやつが一番手前になるという仕組み)
class 適当なクラス : ICompare<スプライト>
int Compare(スプライト a, スプライト b)
{
return b.優先順位 - a.優先順位;
}
ストックObject形式を採用。
各スプライトの使用/未使用はフラグによって切り替えるだけとし、要素は最大スプライト数default値で生成しておく。要素の削除は行わないが以下の優先順位書き換え時にのみ一時的手段として行うものとする。
要素の優先順位の変更は次のように行う
1.該当要素の参照を仮変数tmpに一時退避する
2.リストから該当要素を削除(Remove)する
3.tmpの優先順位を書き換える
4.tmpをリストへ追加(Add)する
※1SortedListの内部仕様
ジェネリックにはキー型と値型の2つ必要であるが、Dictionaryと違ってキーの重複が許される。嘘っぱちでした><キーの重複はダメっぽい・・・。困った
内部ではキーのスカラー配列、値のスカラー配列という2本の配列によって実装されている。
各要素の追加時は
1.キー配列のBinarySearchにより挿入位置を決める
2.挿入位置に対してキー、値とも配列の物理的なブロックコピーにより挿入される
●自作しよっかあ??
うーん。なるべくフレームワーク使って自作は避けたい派なんです。別にコードが膨らむとかじゃなくって人に説明しやすい(なにしろヘルプに説明が載ってる関数だしね)ってのがあるんですが。
どいつもこいつも私の要望満たさないしねえ実際List系のジェネリックなんてコードもすっごいちょろっとだし(SortedListも10分もありゃコードも書けそうなくらい大した実装じゃない)。
色々細工して(キーをユニークにしてみよっとか)やってましたけど、もう諦めてListっぽいのだけは自作しよっかと思い始めました・・。
●んじゃSortedListから派生すれば??
ジェネリックを派生はナンセンス
というのが私の持論。私が変わり者かも知れないのですけど。ジェネリックってのは
「引数で<型>をわたす。ただその情報のみでそれなりの準備は全部完結すべき」
だと思っている。なのでジェネリックの動作が気に入らないって場合、新しく別のジェネリックをこさえるのが筋では無いかと。
この「新しいジェネリック」のために既存ジェネリックから派生はOKなんですよ。ここ重要。
フレームワークだって既存ジェネリックからいくらでも派生してますから。ただ派生先もジェネリックであるべきじゃないかってのが私の言いたい事です。
そもそもジェネリックは簡単に扱えるちっちゃいクラスが多いですし、わざわざ派生拡張みたいな器用な芸して苦労して使わなきゃいけないとも思っていません。そんなの書いてる間にジェネリックじゃない素のコードができちゃいますし。