吃豆子碰撞检测

时间:2012-01-25 08:57:19

标签: math xna

我正在尝试创建一个pacman游戏来学习XNA,但我遇到了一些问题,以使碰撞检测工作。游戏是基于图块的,其中1是墙,0是可步行的。 然后它会占用你站在的瓷砖加上它周围的4,如果它与其中一个碰撞并且瓷砖值不为0,它会将位置重置为移动前的位置。出于某种原因,它只是不起作用,它随机卡住,有时我甚至可以通过墙壁移动。 enter image description here

这是我的碰撞检测:

    var oldPos = Position;
    // Updates the Position
    base.Update(theGameTime, mSpeed, mDirection);

    // Test Collidetion
    Rectangle objRect = new Rectangle((int)Position.X, (int)Position.Y, 32, 32);
    bool isCollided = false;
    Vector2 curTitle = GetCurrentTitle();

    // Test UP, DOWN, LEFT, RIGHT
    int tile;
    Rectangle testRect;

    if ((int)curTitle.Y < 0 || (int)curTitle.X < 0 || (int)curTitle.Y >= map.MapSizeWidth - 1 || (int)curTitle.X >= map.MapSizeHeight - 1)
        isCollided = true;

    if (!isCollided)
    {
        tile = map.Tiles[(int)curTitle.Y, (int)curTitle.X];
        testRect = new Rectangle(((int)curTitle.X) * map.TileSize, ((int)curTitle.Y) * map.TileSize, map.TileSize, map.TileSize);
        if (tile != 0 && rectangle_collision(testRect, objRect))
            isCollided = true;

        if (curTitle.Y != 0)
        {
            tile = map.Tiles[(int)curTitle.Y - 1, (int)curTitle.X];
            testRect = new Rectangle(((int)curTitle.X) * map.TileSize, ((int)curTitle.Y - 1) * map.TileSize, map.TileSize, map.TileSize);
            if (tile != 0 && rectangle_collision(testRect, objRect))
                isCollided = true;
        }

        tile = map.Tiles[(int)curTitle.Y + 1, (int)curTitle.X];
        testRect = new Rectangle(((int)curTitle.X) * map.TileSize, ((int)curTitle.Y - 1) * map.TileSize, map.TileSize, map.TileSize);
        if (tile != 0 && rectangle_collision(testRect, objRect))
            isCollided = true;

        if (curTitle.X != 0)
        {
            tile = map.Tiles[(int)curTitle.Y, (int)curTitle.X - 1];
            testRect = new Rectangle(((int)curTitle.X - 1) * map.TileSize, ((int)curTitle.Y) * map.TileSize, map.TileSize, map.TileSize);
            if (tile != 0 && rectangle_collision(testRect, objRect))
                isCollided = true;
        }

        tile = map.Tiles[(int)curTitle.Y, (int)curTitle.X + 1];
        testRect = new Rectangle(((int)curTitle.X + 1) * map.TileSize, ((int)curTitle.Y) * map.TileSize, map.TileSize, map.TileSize);
        if (tile != 0 && rectangle_collision(testRect, objRect))
            isCollided = true;
    }
    if (isCollided)
        Position = oldPos;

任何人都可以看到我的碰撞检测不起作用的原因吗?

编辑:我已将整个项目上传到http://sogaard.us/Pacman.zip

2 个答案:

答案 0 :(得分:1)

我不确定这是否导致了完整的问题。但是在你的第三张瓷砖检查(你检查下面的瓷砖)上,你正在检查上面的瓷砖。

这部分:

tile = map.Tiles[(int)curTitle.Y + 1, (int)curTitle.X];

在下一行,你仍然可以在testRect的参数内找到它:

((int)curTitle.Y - 1) * map.TileSize

应该是:

((int)curTitle.Y + 1) * map.TileSize

完整更正的代码段:

tile = map.Tiles[(int)curTitle.Y + 1, (int)curTitle.X];
    testRect = new Rectangle(((int)curTitle.X) * map.TileSize, ((int)curTitle.Y + 1) * map.TileSize, map.TileSize, map.TileSize);
    if (tile != 0 && rectangle_collision(testRect, objRect))
        isCollided = true;

希望这有助于:)

答案 1 :(得分:0)

这条线对我来说很奇怪:

testRect = new Rectangle(
    ((int)curTitle.X) * map.TileSize, 
    ((int)curTitle.Y) * map.TileSize, 
    map.TileSize, 
    map.TileSize);

为什么要将X和Y坐标与TileSize相乘?

我不知道Rectangle的参数应该是什么意思,但我假设前两个是位置,最后两个是宽度和高度。我想你打算写

testRect = new Rectangle(
    ((int)curTitle.X), 
    ((int)curTitle.Y), 
    map.TileSize, 
    map.TileSize);