如何解决二维网格中两个矩形之间的碰撞?

How to resolve a collision between two rectangles in a 2D grid?

免责声明:这就是全部(伪代码)

我有一个像这样的数组中的 Tile Map

{0,0,0,0,0,0,0,0,0,0,0
 0,0,0,0,0,0,0,0,0,0,0
 0,0,0,0,0,0,0,0,0,0,0}

然后我使用 for 循环为数组中的每个元素创建一个单独的图块,就像这样

newTile(x,y)

每个方块的宽度和高度都相同,并且 none 个方块在移动。

而玩家可以在整个地图上自由移动,没有任何固定移动。

现在我已经了解了一些背景知识,可以继续解决我的实际问题了。 我在检测是否存在碰撞时没有问题,但实际上解决了碰撞并确定了碰撞发生在哪一边检测到。

我目前的做法如下

function Tiles.collide(self,a,x,y,dt)
  if self:CheckCollide(a.x,a.y) and self.type == "cem" then
    deltaX = a.x - self.x
    deltaY = a.y - self.y
    if(math.abs(deltaX) > math.abs(deltaY))then
      if(deltaX > 0) then
        collText = "Left Wall"
        a.x = a.x + 5
      else
        collText = "Right Wall"
      end
    else
      if(deltaY > 0) then
        collText = "Bottom Wall"
        a.y = a.y + 5
      else
        collText = "North Wall"
      end
    end
  end
end

然后我使用返回的内容并继续实际解决碰撞。

 if(checkSide() == rightSide)
     // What now???

returns 哪边相交的方法没有按预期工作。我也不知道如何解决冲突。这就是为什么我问

http://makeagif.com/i/S3dPR7

鉴于您已经知道发生了碰撞,因此您无需担心播放器和方块的宽度。你只关心玩家在哪一边,所以你可以这样做:(假设 0,0 在 canvas 的左上角)

deltaX = playerX - tileX
deltaY = playerY - tileY
if (abs(deltaX) > abs(deltaY))
    if (deltaX > 0)
        return eastWall
    else
        return westWall
else
    if (deltaY > 0)
        return southWall
    else
        return northWall
end

问题是虽然发生了碰撞,但您不知道玩家在碰撞后移动了多远(我假设您每隔 X 毫秒就停下来寻找碰撞?)。如果玩家非常靠近角落,看起来他们可能与一侧发生碰撞,而实际上他们与相邻的一侧发生了碰撞。一个字面的角落案例。

这个问题有解决办法,但是比较复杂,需要计算碰撞发生的时间,然后查看碰撞发生时场的状态。