【问题标题】:Testing For All Non-collided Tiles in XNA在 XNA 中测试所有未碰撞的瓷砖
【发布时间】:2013-02-27 17:15:56
【问题描述】:

我目前正在用 XNA 编写一个平台游戏。 我的碰撞测试目前通过运行一个 foreach 循环来测试玩家的边界框与每个图块的边界框。但是,我不知道如何测试玩家是否没有接触任何方块。

我将如何遍历我的阵列并测试他们的玩家是否没有接触任何方块,以便我可以检查他是否在半空中?任何帮助或建议将不胜感激。提前谢谢!

///////////////////////////////

我的碰撞码是

    if (personRectangle.TouchTopOf(newRectangle))
    {
         onGround = true;
         test = false;
         test2 = true;
    }

对应的bool测试是

    public static bool TouchTopOf(this Rectangle r1, Rectangle r2)
    {
        return (r1.Bottom >= r2.Top - 1 &&
                r1.Bottom <= r2.Top + (r2.Height / 2) &&
                r1.Right >= r2.Left + (r2.Width / 5) &&
                r1.Left <= r2.Right - (r2.Width / 5));
    }

这段代码在 Game1.cs 更新中测试碰撞。

        foreach (CollisionTiles tile in map.CollisionTiles)
            player.Collision(tile.Rectangle);

这是我的地图类中的瓦片列表

    private List<CollisionTiles> collisionTiles = new List<CollisionTiles>();

【问题讨论】:

    标签: c# foreach xna collision-detection


    【解决方案1】:

    XNA 矩形有一个内置的 intersects 方法:

    if (rect1.Intersects(rect2)){
    ...
    }
    

    只需遍历平铺矩形并在每个矩形上调用 intersects。为了提高效率,您应该将玩家坐标映射到世界坐标并确定离玩家最近的图块,这样做可以缩小需要循环的图块数量。

    编辑:为澄清起见,您可以:

    bool collision=false;
    foreach (CollisionTiles tile in map.CollisionTiles) {
        if(personRectangle.Intersects(tile.Rectangle)) {
            collision =true;
            break;
        }
    }
    

    如果碰撞是真的,你就知道某处发生了碰撞。

    【讨论】:

    • 我不确定我是否明白你的意思。我目前正在使用 rectangle.Top 等方法来测试边界。但是它会测试每个块并感到困惑,因为它触及了一些块而不是其他块,导致 if(true) 和 else(false) 都被触发。我希望它测试它是否没有触及任何块......
    【解决方案2】:

    除非您有理由不这样做,否则请保持简单。只需跟踪您碰撞了多少东西。如果您的计数最终为 0,那么您没有与任何东西发生碰撞。

    不用担心修改/优化您拥有的任何代码,它可能是这样的:

    int touchedCount = 0;
    foreach (CollisionTiles tile in map.CollisionTiles)
    {
            if (player.Collision(tile.Rectangle))
            {
                 touchedCount++;
            }
    }
    
    if (touchedCount == 0)
    {
        //You did not collide with anything
    }
    

    然后在您的碰撞方法中执行类似的操作来跟踪您的检查以及是否发生碰撞。正如其他答案所暗示的那样,使用 Rectangle.Intersects 这可能是最简单的。

    【讨论】:

    • 您的代码不正确,如果您不与任何东西发生碰撞,touchCount 将非零。您可以将增量放在 if 中,但不会检测到其他方面的碰撞
    • 哈。即使这样认为我的代码是错误的。我明白你现在的意思了。我相信我的编辑仍然解决了这个问题。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多