【问题标题】:C# XNA Space Invaders issueC# XNA Space Invaders 问题
【发布时间】:2015-10-02 06:10:01
【问题描述】:

我正在 XNA 4.0 中使用 C# 制作 Space Invaders 克隆,但遇到了几个问题。第一个是当我射击阵列右侧一列但最上面的所有入侵者时,入侵者会移出屏幕,直到下一列达到预定限制;然后整个阵列向下移动。显然我希望它仍然能够检测到剩余的入侵者。我很确定问题出在以下代码部分,但我不确定问题出在哪里。

    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;
            }
        }

第二个问题是,如果我摧毁除一行入侵者之外的所有入侵者,我会在这段代码上收到“NullReferenceException was unhandled”通知:

    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);
                }
            }
    }

再次,不确定问题是什么。以下是检测剩余入侵者的代码:

    // 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;
            }
        }

非常感谢您对这两个问题的任何帮助。

【问题讨论】:

  • 您的第一个循环没有在 0 索引中迭代,这是预期的行为吗?不应该是 rows >= 0 和 cols >=0?
  • 另外,您的 break 语句只会中断内部循环。外循环继续,这可能不是你想要的。引入一个变量来决定是否继续外循环。如果没有找到合适的元素,RightInvader 可能是 null。你应该在访问它的GetXPos()之前检查一下。
  • 当您“杀死”入侵者时,您可能需要发布用于修改 InvaderArray 的代码。您是否将其设置为 null 或其他值?

标签: c# xna


【解决方案1】:

因此,您可能会遇到一些错误。查看您的代码,您似乎在任何地方都使用了很多“魔术”数字。第一步是删除所有 4s、10s、5s 和 11s,并创建一些公共常量:

static readonly int NumRows = 5;
static readonly int NumColumns = 11;

现在,您的代码的第一部分目前从未测试第 0 行或第 0 列,这可能会导致您看到的一些错误。 你的循环现在可以写成:

for (int rows = NumRows - 1; rows >= 0; rows--)
    for (int cols = NumCols - 1; cols >= 0; cols--)

目前,您的循环从未测试 col 或 row 0。

编辑: 我错过了“休息”问题。一个简单的解决方法是:

bool found = false;
for (int rows = NumRows - 1; rows >= 0 && !found; rows--)
    for (int cols = NumCols - 1; cols >= 0 && !found; cols--)

然后将 found 设置为 true 而不是中断。 另一种方法是将嵌套循环放在一个函数中,并在找到所需内容时返回。

例如,你找到的函数可以写成:

for (int rows = 0; rows < NumRows ; rows++)
    for (int cols = 0; cols < NumCols; cols++)
    {
        if (InvaderArray[rows, cols] != null)
        {
            return true;
        }
    }
}
return false;

【讨论】:

  • 那么对于第一个位,我应该在RightInvader = InvaderArray[rows, cols];之后将find设置为true?
  • 之前或之后。下一次循环时,!found 将是假的,它会从两个 for 循环中逃脱。当然,如果您将整个内容嵌套在一个名为 GetRightInvader 的函数中,则可以改为在此时返回 InvaderArray[row, col]。
  • 好的,我将它添加到我的左手和右手入侵者检测器,但我现在在设置左右边缘限制的代码上得到一个“NullReferenceExeption 未处理”,是吗?也需要对他们做点什么吗?
  • 有问题的代码在这里:link
  • 你的问题是这里的这一行:if (RightInvader.GetXPos() &gt; 800)。如果 RightInvader 为空,会发生什么情况。
猜你喜欢
  • 2013-11-06
  • 1970-01-01
  • 2021-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多