0

私はC#を学ぶためにいくつかの演習を行ってきました. XNAをやっていて、スペースインベーダーのクローンを作っています。

これまでのところ、すべてがダンディですが、コーディング中にいくつかの壁に出くわしました。

問題とサポート コードは次のとおりです。

侵略者の列の一番上には 2 つのヘルス ポイントがあり、2 ヒットして破壊し、より多くのポイントを獲得します。ただし、1つがヒットして破壊されると、残りの行の上部は1 HPに減少し、1ヒットで破壊されます-これは私の望ましい結果ではありません.

私が疑う問題のあるコードは次のとおりです。

 if (playerBullet != null && Type1Invaders != null)
        {
            Rectangle rectMissile = new Rectangle((int)playerBullet.getX(), playerBullet.getY(), playerBulletIMG.Width, playerBulletIMG.Height);
            for (int count = 0; count < 11; count++)
            {
                Rectangle rectInvader = new Rectangle(Type1Invaders[count].getX(), Type1Invaders[count].getY(), invader1.Width, invader1.Height);
                if (Type1Invaders[count].getVis() && rectMissile.Intersects(rectInvader))
                {
                    Type1Invaders[count].setHP(Type1Invaders[count].getHP() - 1);
                    shootTimer = 0;
                    if (Type1Invaders[count].getHP() == 0)
                    {
                        explosionInstance.Play();
                        playerBullet = null;
                        Type1Invaders[count].setVis(false);
                        score = score + Type1Invaders[count].getPointValue();

                    }
                }
            }
        }

2 番目のエラーは、左端と右端の侵入者を連続して検出する方法にあります。行全体が破棄されると、nullreference エラーが発生します。(それらは悪夢です..)

とにかく、これは問題のあるコードです

一番左と右のインベーダーを見つける方法

var LeftMost5 = Type5Invaders.Where(i => i.getVis()).FirstOrDefault();
var RightMost5 = Type5Invaders.Where(i => i.getVis()).LastOrDefault();

そしてifステートメントはnullエラーをスローしています

 if (RightMost5.getX() >= RightGameEdge)
        {
            Type5.setDir(-1);
            for (int count = 0; count < 11; count++)
            {
                invaderMoveInstance5.Play();
                Type5Invaders[count].MoveY(8);
            }
        }

これは一番右側でのみ発生しますが、左側でも発生すると想定できます。同じロジックを適用して、このエラーを左側にも修正できると想定しています。

これで十分でない場合は、より多くの情報とスニペットを提供できます。

助けてくれてありがとう!

4

1 に答える 1

3

創刊号用。弾丸が侵略者を殺すとき、その弾丸は別の侵略者を殺さないと言うことができると思います. break;したがって、ループを停止するために a を追加できます。このような:

if (Type1Invaders[count].getVis() && rectMissile.Intersects(rectInvader))
{
  Type1Invaders[count].setHP(Type1Invaders[count].getHP() - 1);
  shootTimer = 0;
  if (Type1Invaders[count].getHP() == 0)
  {
    explosionInstance.Play();
    playerBullet = null;
    Type1Invaders[count].setVis(false);
    score = score + Type1Invaders[count].getPointValue();
  }
  break;
}

2 番目のエラーでは、コレクションが空の場合 (タイプ 5 のインベーダーをすべて倒した後) 、FirstOrDefaultメソッドが返されます。null次のように、null かどうかを確認するだけです。

var LeftMost5 = Type5Invaders.Where(i => i.getVis()).FirstOrDefault();
var RightMost5 = Type5Invaders.Where(i => i.getVis()).LastOrDefault();

if(RightMost5 != null)
{
    // this means we have a non-null invader
    if (RightMost5.getX() >= RightGameEdge)
    {
        Type5.setDir(-1);
        for (int count = 0; count < 11; count++)
        {
            invaderMoveInstance5.Play();
            Type5Invaders[count].MoveY(8);
        }
    }
}
else
{
    //this means that the invader does not exist anymore, so we do nothing
}
于 2012-04-19T12:12:21.303 に答える