【问题标题】:for-in-loop/ Condition Is only used for the first element of the a List [closed]for-in-loop/ Condition 仅用于列表的第一个元素[关闭]
【发布时间】:2011-10-19 13:49:59
【问题描述】:

找了三天也没找到解决办法,代码如下:

if (keyboardState.IsKeyDown(Keys.Right))
{
    for (int i = GlobalClass.BlocksPositions.Count - 1; i > 0; i--)
    {
        if (new Rectangle((int)GlobalClass.BlocksPositions[i].X, (int)GlobalClass.BlocksPositions[i].Y, bT.Width, bT.Height).Intersects(new Rectangle((int)Position.X, (int)Position.Y, Texture.Width, Texture.Height)))
        {

            c = 0;
        }
        else
        {
            c = 1;
        }
    }

    if (c == 1)
    {
        Position.X += Speed;
    }

}

每个方块位置等于我可以通过单击屏幕创建的方块,然后将新的方块位置放入列表中。基本上,我的 BlockPosition 列表中有一个块坐标列表。然后我传递每个块位置的条件,条件为每个块位置创建一个矩形,为玩家创建一个矩形......如果发生碰撞,玩家将不会朝那个方向移动。当我尝试代码时,我的角色只会与列表的第一个元素而不是其他元素发生碰撞,如果我删除第一个元素,它将与下一个元素发生碰撞,但不会与其他元素发生碰撞。所有变量都很好我知道,因为我试图用这样的东西替换这段代码:

if (keyboardState.IsKeyDown(Keys.Right))
{
    for (int i = GlobalClass.BlocksPositions.Count - 1; i > 0; i--)
    {
        if (new Rectangle((int)GlobalClass.BlocksPositions[i].X, (int)GlobalClass.BlocksPositions[i].Y, bT.Width, bT.Height).Intersects(new Rectangle((int)Position.X, (int)Position.Y, Texture.Width, Texture.Height)))
        {
            GlobalClass.BlocksPositions.RemoveAt[i];

        }
    }
}

同样的事情,但是如果它发生碰撞,我会删除列表中的元素,这是相同的条件,但是当我尝试它时,它会检测到所有元素并删除我触摸的元素。我尝试了 foreach 函数,得到了相同的结果。怎么了?我已经用 dos 变量做了很多事情所以我确信问题不是来自它们的值,而是来自我对它们所做的事情。请帮忙! (:

【问题讨论】:

  • 没关系,我找到了!我只需要在 c = 0;

标签: c# list indexing conditional-statements for-in-loop


【解决方案1】:

如果if 的计算结果为true,你什么都不做,而且你似乎也不需要c 变量。怎么样...

if (keyboardState.IsKeyDown(Keys.Right))
{
    foreach( var pos in GlobalClass.BlocksPositions.Reverse() )
    {
        var rect = new Rectangle((int)pos.X, (int)pos.Y, bT.Width, bT.Height);
        var rectToTest = new Rectangle((int)Position.X, (int)Position.Y, Texture.Width, Texture.Height);
        if (!rect.IntersectsWith(rectToTest))
            Position.X += Speed;
        else
            break;
    }
}

如果您确实需要 c 进行某种状态管理,那么您可以将其重新添加。

【讨论】:

    【解决方案2】:

    即使您找到了一个交叉点,您的循环也会继续。您需要在 if 语句的 true 子句中中断。

    【讨论】:

      【解决方案3】:

      为了可读性,考虑这样的事情:

      if (GlobalClass.BlocksPositions.All(x => !DoesIntersect(Position, x))
           Position.X += speed;
      

      不仅目的更容易推断,而且你所犯的特定错误也不会出现。

      【讨论】:

      • 这会改变代码的语义。在您的示例中,X 位置最多会更新一次,但在 OP 中,对于在找到交叉点之前不相交的每个矩形,它都会增加。
      • 不真实。 Position.X 在 for 循环之外被修改,并且专门嵌套在两个 if 块中,因此在此代码片段中它只能在逻辑上执行一次。在他的情况下,只有当集合中的最后一个块和位置不相交时才会发生这种增量。找到交叉点时没有指定中断条件。
      猜你喜欢
      • 2011-10-19
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      • 2022-06-16
      • 2020-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多