Witam, chciałbym się dowiedzieć, jaka jest najlepsza struktura obiektów dla gry typu Tower Defense w XNA, komunikacja między obiektami.
Obecnie stworzyłem klasę CStage:

public class CStage
{
    //obiekty w grze
    public List<CEnemy> Enemies;    //lista wszystkich przeciwników
    public List<CTower> Towers; //lista wszystkich wieżyczek
    public List<CBullet> Bullets;   //lista wszystkich pocisków
    public List<Vector2> Way;   //lista punktów budujących drogę mapy

/* ... */

 public void Update(GameTime gameTime)
        {
            for (int i = 0; i < Enemies.Count(); ++i)
                if (Enemies[i] != null)
                    Enemies[i].Update(gameTime);
            for (int i = 0; i < Towers.Count(); ++i)
                if (Towers[i] != null)
                    Towers[i].Update(gameTime);
            for (int i = 0; i < Bullets.Count(); ++i)
                if (Bullets[i] != null)
                    Bullets[i].Update(gameTime);
        }
/* ... */

Funkcja public void Draw(SpriteBatch spriteBatch, GameTime gameTime) wygląda tak samo, jak Update.
Tutaj mam pytanie, czy lepsza jest taka konstrukcja, którą zastosowałem powyżej z pętlą for, czy może lepiej użyć
foreach(CEnemy enemy in Enemies) { /* ... */} ?

Chciałbym też zadbać o sprzątanie danych, szczególnie w tablicy Bullets. Wiadomo, że różne obiekty będą się pojawiać w grze, oraz znikać. Moje obecne rozwiązanie, to funkcja wewnątrz CStage:

public void Check()
{
	for (int i = 0; i < Enemies.Count(); ++i)
		if (Enemies[i] != null)
			if (!Enemies[i].Check())
				Enemies[i] = null;
	for (int i = 0; i < Towers.Count(); ++i)
		if (Towers[i] != null)
			if (!Towers[i].Check())
				Towers[i] = null;
	for (int i = 0; i < Bullets.Count(); ++i)
		if (Bullets[i] != null)
			if (!Bullets[i].Check())
				Bullets[i] = null;
}

Funkcja Check() jest typu bool i zwraca zmienną w zależności, czy ten obiekt powinien być jeszcze zauważany, czy nie powinno go już być (np. przeciwnik, który zginął zwróci false, pocisk, który w coś uderzy zwróci false, wieżyczka po sprzedaży też false itd.)
Tak więc za pomocą tego prostego systemu wyrzucam konkretne obiekty z listy zastępując je nullem. Niestety miejsce zarezerwowane na te obiekty nadal jest zablokowany. Chciałbym, by lista była odświeżana, i tak jakby przepisywane listy od nowa, opuszczając wolne indeksy. Ogólnie w tej metodzie nigdzie, w żaden sposób nie zachowuje indeksów obiektów - to dobrze? Może tak być, czy brak indeksów obiektów w końcu zwiąże mi ręce i uniemożliwi wykonanie pewnych procedur?

Pozdrawiam!