2

...

我有一个球,我可以在由相同大小的瓷砖组成的地图上四处移动。玩家不应该能够走过较暗且有黑色边框的瓷砖。我有一个多维的瓷砖数组,用于检查哪些瓷砖是实心的。

如果玩家在水平和垂直方向上移动,我希望玩家靠墙滑动。问题是,如果他这样做,他会坚持下去。我设法让它在每个轴上完美地工作,但分开。这是我的水平碰撞检查代码:

if (vx < 0) {
    // checks for solid tiles left of the player
    if (level.isBlocked(i, j) || level.isBlocked(i, jj)) {
        x = side * (i + 1); // moves player to left side of tile
        vx = 0;
    }
} else if (vx > 0) {
    // checks for solid tiles right of the player
    if (level.isBlocked(ii, j) || level.isBlocked(ii, jj)) {
        x = (ii * side) - getWidth(); // moves player to right side of tile
        vx = 0;
    }
}

level.isBlocked ()方法检查数组的索引是否被实心图块占用。ij变量是玩家右上角所在数组中的哪个索引。iijj变量是玩家右下角所在数组中的哪个索引。

这很好用,但是如果我在下面添加相同的代码块,但将x替换为y,将vx替换为vy等等,就会出现问题。所以我可以添加水平或垂直碰撞处理,它可以工作,但不能同时进行。我看过一些文章解释我必须将它们分开或其他东西,但我不太了解它们。如何检查两个轴上的碰撞并保持滑动效果?

4

2 回答 2

2

我终于让它工作了。Angelatlarge 的回答有助于理解问题,但我决定从头开始。我最终首先计算了新的 x 和 y 位置并将它们存储在单独的变量中。然后我检查了播放器左中下方的瓷砖,与中右相同。然后,如果玩家由于水平速度而站在瓷砖上,我将布尔值设置为 true。如果没有碰撞,我将实际 x 变量设置为我之前计算的新变量。然后我对垂直碰撞重复了同样的事情。

这是用于水平检查:

float newX = x + vx * delta;
boolean xCollision = false;
if (vx < 0) {
    int i = level.toIndex(x);
    int j = level.toIndex(y + getHeight() / 2);
    xCollision = level.isBlocked(i, j);
} else if (vx > 0) {
    int i = level.toIndex(x + getWidth());
    int j = level.toIndex(y + getHeight() / 2);
    xCollision = level.isBlocked(i, j);
}
if (!xCollision) x = newX;
于 2013-03-21T11:09:34.327 回答
1

问题是,在你所拥有的设置中,给定一个方块和玩家位置,并且考虑到它们重叠的事实,你不知道玩家是与方块的垂直墙还是水平墙发生碰撞。所以更清楚地看到这个考虑以下块和两个碰撞路径 在此处输入图像描述

顶部路径将与左壁碰撞,需要vx=0;(停止水平移动),而底部路径与底部壁碰撞,需要 vy=0;或停止垂直移动。

我认为为了进行您想要的那种碰撞检测,您需要计算玩家路径和方块墙壁的交点,而不仅仅是检查玩家是否与方块重叠。您可以通过计算播放器矩形和块矩形的重叠矩形来破解所需的行为。考虑以下情况:

在此处输入图像描述

其中红色的 seqare 代表您的播放器。重叠矩形(玩家位于方块顶部的小矩形)比其高更宽,这表明发生了垂直碰撞,而不是水平碰撞。然而,这并非万无一失。它仍然要求您能够访问块的形状,而不仅仅是测试玩家矩形的一部分是否与块重叠。

于 2013-03-09T20:28:08.373 回答