Reputation: 57
I'm making a Space Invaders clone using C# in XNA 4.0 and I've run into a couple of issues. The first is that when I shoot all of the invaders on the right-hand side column of the array but the very top one, that invader moves off-screen until the next column reaches the predetermined limit; then the entire array moves down. Obviously I want it to still detect the remaining invader. I'm pretty sure the issue is with the following section of code, but I'm not sure what the problem is.
for (int rows = 4; rows > 0; rows--) // Detects right-most invader
for (int cols = 10; cols > 0; cols--)
{
if (InvaderArray[rows, cols] != null)
{
RightInvader = InvaderArray[rows, cols];
break;
}
}
The second issue is that if I destroy all but one row of invaders I get a 'NullReferenceException was unhandled' notification on this piece of code:
if (RightInvader.GetXPos() > 800) // Right edge limit
{
InvaderDir = -1;
for (int rows = 0; rows < 5; rows++)
for (int cols = 0; cols < 11; cols++)
{
if (InvaderArray[rows, cols] != null)
{
InvaderArray[rows, cols].MoveVertical(8);
}
}
}
Again, not sure what the problem is. The following is the code for detecting the remaining invader:
// Detecting remaining invader
bool InvaderFound = false;
for (int rows = 0; rows < 5; rows++)
for (int cols = 0; cols < 11; cols++)
{
if (InvaderArray[rows, cols] != null)
{
InvaderFound = true;
break;
}
}
Any help with either issue is greatly appreciated.
Upvotes: 1
Views: 145
Reputation: 376
So you might be suffering from some off by one errors. Looking at your code, it looks like you use a lot of 'magic' numbers everywhere. The first step would be to remove all the 4s, 10s, 5s, and 11s, and create some public constants:
static readonly int NumRows = 5;
static readonly int NumColumns = 11;
Now, the first section of your code currently never tests the 0th row or column, which could be leading to some of the badness you're seeing. Your loops could now be written as:
for (int rows = NumRows - 1; rows >= 0; rows--)
for (int cols = NumCols - 1; cols >= 0; cols--)
Currently, your loop was never testing col or row 0.
Edit: I missed the 'break' problem. An easy way to solve that is:
bool found = false;
for (int rows = NumRows - 1; rows >= 0 && !found; rows--)
for (int cols = NumCols - 1; cols >= 0 && !found; cols--)
then set found to true instead of breaking. Another way is to place your nested loops inside a function, and return when you find what you want.
For example, your found function could be written:
for (int rows = 0; rows < NumRows ; rows++)
for (int cols = 0; cols < NumCols; cols++)
{
if (InvaderArray[rows, cols] != null)
{
return true;
}
}
}
return false;
Upvotes: 2