foreach

前回、Platformerにはfor文しか使われてないなどと書いたのだが、 明らかな認識ミスでやはり主にforeachが使われていた。 たとえばLevel.csのDraw()メソッドの中の

foreach (Gem gem in gems) gem.Draw(gameTime, spriteBatch);

とか

foreach (Enemy enemy in enemies) enemy.Draw(gameTime, spriteBatch);

とか。わざわざforループ使ってるのは一部の特殊なケースだけ。 たとえばLevel.csのUpdateGems()メソッドの

            for (int i = 0; i < gems.Count; ++i)
            {
                Gem gem = gems[i];
                gem.Update(gameTime);
                if (gem.BoundingCircle.Intersects(Player.BoundingRectangle))
                {
                    gems.RemoveAt(i--);
                    OnGemCollected(gem, Player);
                }
            }

これはgemsというリストから要素を取り除くためにforループを必要としているというわけだ。

playerが死んだら出発地点からやり直すのだが、 出発地点にmonsterが居ると、 死ぬたび瞬殺されてゲームとして成立しない。 出発地点までmosterが移動できないようなマップにすれば回避できるわけだが、 まあ一種のバグと言って良いだろう。 で、playerが出発地点に戻ると同時にmonsterも初期位置に戻るようにすればよく、 Level.csの中のStartNewLife()と言うメソッドを

        public void StartNewLife()
        {
            Player.Reset(start);

            foreach (Enemy enemy in enemies)
            {
                enemy.Reset();
            }
        }

のように変更し、 EnemyクラスにReset()というメソッドを追加すれば良い。 Reset()は、たとえばEnemyクラスにprivate Vector2 position_init;など用意して、 コンストラクタでpositionの値をposition_initに退避しておき、 Reset()の中でposition = position_init;などと書けばよかろう。