【问题标题】:LibGDX - Collision detection between Player and a Platform (or tile) WITHOUT using TiledMapLibGDX - 玩家和平台(或瓷砖)之间的碰撞检测,而不使用 TiledMap
【发布时间】:2015-01-20 19:58:22
【问题描述】:

在我的游戏中,角色不断地从左向右移动,所以永远不会出现他撞到平台右侧的情况。我与某人进行了非常简短的交谈,他建议我将我的平台建模为 4 个矩形,这样我的算法中只需要 3 个案例(即 Player 只能与下图)。这是我的意思的视觉描述:

我试了一下,但碰撞检测仍然一团糟。它不会穿过平台的一侧(这是个好消息,因为我们希望这种情况发生),但您不能在它上面滑行或在它下面弹跳。谁能看到我哪里出错了?

public void checkCollisions(ArrayList<GameObject> list) {

    for (int i = 0; i < list.size(); i++) {
        for (int j = i + 1; j < list.size(); j++) {
            GameObject go1 = list.get(i);
            GameObject go2 = list.get(j);
            boolean playerPlatformCollision = go1.getType()
                    .equalsIgnoreCase("player") && go2.getType().equalsIgnoreCase("platform");
            if (playerPlatformCollision) {
              Rectangle playerRect = go1.getRect();
              Rectangle platformRect = go2.getRect();
                if (playerRect.overlaps(platformRect)) {

                    float platformRectX, platformRectY, platformRectWidth, platformRectHeight;
                    platformRectX = go2.getRect().getX(); // x position of the platform
                    platformRectY = go2.getRect().getY(); // y position of the platform
                    platformRectWidth = go2.getRect().getWidth(); // width of platform
                    platformRectHeight = go2.getRect().getHeight(); // height of platform

                    Rectangle caseA = new Rectangle(platformRectX,
                            platformRectY, platformRectX + 1,
                            platformRectHeight);
                    Rectangle caseB = new Rectangle(platformRectX + 1,
                            (platformRectY + platformRectHeight) - 1,
                            platformRectWidth - 1, platformRectHeight);
                    Rectangle caseC = new Rectangle(platformRectX + 1,
                            platformRectY, platformRectWidth, 1);

                    if (playerRect.overlaps(caseA)) {
                        go1.setxSpeed(0);
                    } else if (playerRect.overlaps(caseB)) {
                        go1.setySpeed(0);
                    } else if (playerRect.overlaps(caseC)) {
                        go1.setySpeed(-3f);
                    }
                }
            }
        }
    }
} 

如果您对代码的任何部分不清楚,请告诉我。

【问题讨论】:

  • 对不起我的英语,但我不清楚问题是什么,如果我能澄清一下,也许我可以提供帮助
  • 如果你看看我的新编辑可能更有意义。我正在尝试在 Player 和 Platform/Tile 之间实现 mario 风格的碰撞检测。玩家可以通过 3 种不同的方式与平台碰撞;通过撞击平台侧面(图中的案例 A)、平台顶部或平台底部。当他接触案例 A 时,我希望玩家的水平速度为 0(因此他不会通过平台),当他接触案例 B 时,我希望他的垂直速度为 0(因此他不会跌落平台)和案例C:反弹。
  • case 矩形的宽度为 1 像素。案例 B 和 C 矩形的高度为 1 像素
  • 是的,为什么宽度/高度只有 1 个像素?你的播放器移动的速度有多快。他可以轻松跳过该像素并最终进入红色区域。可能最准确的检测技术是存储以前的坐标。因此,当玩家最终进入某个图块时,您在当前和前一个玩家位置之间“绘制”一条线,并计算该线和图块边缘之间的交点。然后检查哪条边相交 - 顶部、左侧或右侧。稍微复杂一点,但可能更可靠。
  • 你是对的,也许 1 像素宽/高是个坏主意。您是否知道任何演示您所指技术的教程或指南?

标签: java android libgdx collision-detection physics


【解决方案1】:

我不能确定这就是问题所在,但您的代码中似乎没有解决这个问题,我自己在忽略这个问题时也遇到了类似的问题。当您的播放器与平台发生碰撞时,这意味着它的矩形已经与平台相交,相差介于 1 和您的移动速度之间的像素数。仅调整 x 和 y 速度是不够的。您还必须从平台上移除播放器矩形,否则播放器会卡住。这可以通过使用循环并检查您的玩家是否仍在碰撞来完成。如果是这样,请向原来的方向移动 1 个像素,直到不再发生碰撞。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 1970-01-01
    相关资源
    最近更新 更多