沿着墙壁滑动的瓷砖碰撞

时间:2013-03-09 19:10:48

标签: java slide collision tile

...

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

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

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()方法检查数组的索引是否被实体图块占用。 i j 变量是玩家右上角所在阵列中的哪个索引。 ii jj 变量是玩家右下角所在阵列中的哪个索引。

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

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

问题在于,根据你的设置,给定一个区块和玩家位置,并且考虑到它们重叠的事实,你不知道玩家是否与区块的垂直或水平墙碰撞。因此,请更清楚地考虑以下块和两个冲突路径 enter image description here

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

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

enter image description here

红色seqare代表你的玩家。重叠矩形(玩家在块顶部占据的小矩形)比高暗示发生的垂直碰撞更宽,而不是水平。然而,这并非万无一失。它仍然要求您能够访问块的形状,而不是仅仅在播放器矩形的一部分与块重叠时才进行操作。