在XNA中测试所有非碰撞的瓷砖

时间:2013-02-27 17:15:56

标签: c# foreach xna collision-detection

我目前正在XNA中编写一款平台游戏。 我的碰撞测试目前通过运行foreach循环测试每个tile的边界框的玩家的边界框来运行。但是,我无法弄清楚如何测试玩家是否没有碰到任何街区。

如果他们的玩家没有碰到任何街区,我将如何通过我的阵列进行测试,以便我可以检查他是否在半空中?任何帮助或建议将不胜感激。提前谢谢!

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

我的碰撞代码是

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

相应的布尔测试是

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

2 个答案:

答案 0 :(得分:3)

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

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

只需遍历tile矩形并在每个矩形上调用相交。为了提高效率,您应该将播放器坐标映射到世界坐标上并确定最接近播放器的贴片,这样做可以缩小需要循环的贴片数量。

编辑:澄清一下,你可以:

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

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

答案 1 :(得分:0)

除非你有理由不这样做,否则请保持简单。只需跟踪您碰撞的事物数量。如果你的计数最终为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这可能是最容易的,正如另一个答案所暗示的那样。