1

我在我的自上而下的游戏中实现了一个简单的基于瓷砖的碰撞系统,但我在通过角落移动时遇到了问题。目前,我的程序以玩家的中心点为中心,在 20 像素的方形网格(交替的灰色 cbackground)上绘制一个图块。它检查上下左右的瓷砖是否有碰撞,如果找到,则进入下一个阶段。

下一阶段是检查玩家在瓷砖内的位置。为此,我有一个名为getCenterDistanceFromCurrentTile()(创意名称,我知道)的函数。这将返回从图块中心点到玩家中心点的距离的 Vector2i(x 和 y)。然后我通过以下方式使用它;

  • 如果左边有一块墙砖,并且玩家的 x 距离 < 0(玩家在当前图块中心点的左侧),则玩家将移动到靠近墙的图块的 x 处。
  • 如果右侧有一堵墙,并且玩家的 x 距离 > 0(当前图块中心点的右侧),则玩家将移动到墙旁边图块的 x 处。
  • Y 轴以同样的方式继续。

我的问题是对角线。我目前不检查对角线碰撞,但看来我必须这样做。我已经尝试实现它,但是玩家在碰到角落时会跳来跳去。我正在使用上面的玩家 x < 0 和玩家 y < 0 的方法,但没有成功。我制作了一些图片来更好地解释我的问题。

问题图片 1

这张图片展示了我的碰撞系统工作正常,左侧有碰撞(由蓝色瓷砖显示),粉色瓷砖正在检查,但没有发现碰撞。绿色方块显示玩家当前的方块,红色方块显示玩家的当前位置。

问题图片 2

这张图片清楚地显示了我遇到的问题。粉红色的瓷砖都没有碰撞到任何东西,因此玩家的 x 和 y 不需要检查。

我应该如何检查我的游戏中的角碰撞?

我当前的碰撞检查代码;

public boolean isWall(Vector2i loc)
{
    return this.isWall(loc.x, loc.y);
}

public boolean isWall(int x, int y)
{
    if (x < 0) return true;
    if (y < 0) return true;
    if (y > map[0].length-1) return true;
    if (x > map.length-1) return true;
    return map[x][y];
}

public void phys(Player plr) {
    Vector2i playerTile = plr.getTile();
    // Left
    if (isWall(playerTile.x-1, playerTile.y))
    {
        Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true);
        if (distanceFromTile.x < 0)
        {
            plr.setX(playerTile.x*BLOCK_SIZE);
        }
    }
    // Right
    if (isWall(playerTile.x+1, playerTile.y))
    {
        Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true);
        if (distanceFromTile.x > 0)
        {
            plr.setX(playerTile.x*BLOCK_SIZE);
        }
    }
    // Up
    if (isWall(playerTile.x, playerTile.y-1))
    {
        Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true);
        if (distanceFromTile.y < 0)
        {
            plr.setY(playerTile.y*BLOCK_SIZE);
        }
    }
    // Down
    if (isWall(playerTile.x, playerTile.y+1))
    {
        Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true);
        if (distanceFromTile.y > 0)
        {
            plr.setY(playerTile.y*BLOCK_SIZE);
        }
    }
}
4

1 回答 1

1

您的 phys 方法可能会返回布尔值,具体取决于玩家是否与任何墙壁发生碰撞。然后,您可以使用此函数的结果来决定是否返回到您在移动之前所在的空间中的先前位置,或者如果您没有碰撞,则继续前进。

这将要求您检查玩家周围的所有相邻墙壁。这将引入一种更简洁的方式来迭代 phys 方法中的碰撞检查。

这样的改进看起来像:

public boolean phys(Player plr)
{
    java.awt.Rectangle playerBounds = new java.awt.Rectangle(plr.x, plr.y, BLOCK_SIZE, BLOCK_SIZE);

    for (int y = 0; y < 3; y++)
    {
        for (int x = 0; x < 3; x++)
        {
            // Skip the tile the player is on assuming that he is not on a wall already
            if (x == 1 && y == 1) continue;

            java.awt.Rectangle bounds = new java.awt.Rectangle(/*tile at (x, y) xpos*/, /*tile at (x, y) ypos*/, BLOCK_SIZE, BLOCK_SIZE);

            if (bounds.intersects(playerBounds))
            {
                return true;
            }
        }
    }

    // Did not collide
    return false;
}
于 2013-01-08T00:42:14.177 回答