めざせお手軽で富豪的なSTGアーキテクチャー(5)

制御と描画の周辺について。
オブジェクトの存在を管理する仕組みが前回までで出来上がったので、あとはそれらのタスク(制御処理と描画処理)を順次実行できるようにすればいいわけです。
XNAではモデルの操作はGame.Update、描画はGame.Drawという二つのメソッドに分離されて呼び出されます。なので、モデル側も必然的に操作処理と描画処理を分ける必要がありますが、これは別にXNAに限らず分けておくべき物(モデルのコントロールとビュー)なので普通に分けますが。
オブジェクトごとに描画と制御のメソッドがあればいいわけですから、

public class GmObject {
    bool ControleTask(RectangleF MarginalField);
    void DrawTask(IDrawer2D drawer);
}

こんな感じのメソッドを追加します。
MarginalFieldはオブジェクトが存在できる範囲を表す矩形で、GmObjectの中心点(Position)がこの矩形からはみ出すとオブジェクトはDisposeされます。drawerはXNAのSpliteBatch.Drawと橋渡しするためのインターフェースで、回転拡大透過転送を行うための操作の集合体だと思ってください。
制御タスクの戻り値がboolなのは、制御の結果オブジェクトが解体される可能性があるため、生きているか死んでいるかを返すようにすることで死んだオブジェクトをタスクリストから除外できるようにするためです。
具体的には、タスクの呼び出し部分は以下のようにします。

public class GmObjectManager {
    private List<GmObject> tasks = new List<GmObject>();
    public void ControleTask(RectangleF marginalField){
        tasks.RemoveAll(delegate(GmObject task){
            return !task.ControleTask(MarginalField);});
        if (tasksAdder.Count != 0){
            tasks.AddRange(tasksAdder);
            tasksAdder.Clear();
        }
    }
}

RemoveAllを使うことでtasksの全要素に対してControleTaskを呼び出し、その戻り値がfalse(死んでる)であればタスクから除去すると言う一連の作業を一度に行います。その間に他のオブジェクトが生成されることがあるので、新しいオブジェクトはイベント(GmObject.OnCreated)経由でregistorGmObjectが実行されたときに、別のリスト(taskAdder)に溜めておき、あとでまとめてマージします。
DrawTaskも同じようにしますが、こっちは途中でオブジェクトが死んだりしないので普通にforeachで呼び出せば良いでしょう。生成順=描画順になってしまうんですが、近年ではスプライトの上下関係はz軸を使って容易に制御可能なので、それが問題になることは(たぶん)ありません。