繁体   English   中英

基于图块的碰撞; 拐角碰撞问题

[英]Tile-based collision; Corner collision problems

我在自上而下的游戏中实现了一个简单的基于图块的碰撞系统,但是在转弯时遇到了问题。 目前,我的程序以玩家的中心点为基准,并在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);
        }
    }
}

您的phys方法可以返回boolean值,具体取决于玩家是否与任何墙壁碰撞。 然后,您可以使用此功能的结果来决定是返回到您移动之前的空间的先前位置,还是如果没有碰撞,则继续操作。

这将要求您检查播放器周围的所有相邻墙壁。 这将引入一种更干净的方法来迭代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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM