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

时间:2015-12-01 23:06:38

标签: collision-detection 2d-games

免责声明:这就是全部(PSEUDOCODE)

我有一个像这样的数组中的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循环为数组中的每个元素创建一个单独的tile,如此

newTile(x,y)

每个瓷砖都具有相同的宽度和高度,并且没有任何瓷砖在移动。

虽然玩家可以在整个地图中自由移动而没有任何固定的移动。

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

我目前的做法如下

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???

返回正在交叉的一侧的方法并不按预期工作。我也不知道如何解决碰撞。这就是我问的原因

http://makeagif.com/i/S3dPR7

  

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

1 个答案:

答案 0 :(得分:1)

看到您已经知道发生了碰撞,您无需担心播放器和磁贴的宽度。你只关心玩家在哪一边,所以你可以这样做:(假设0,0在画布的左上角)

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毫秒停一次并寻找碰撞?)。如果玩家非常接近角落,当它们实际上与相邻侧面碰撞时,它们看起来可能与一侧发生碰撞。字面角落案例。

这个问题有解决方案,但它们更复杂,涉及计算碰撞发生的时间,然后查看碰撞发生时的场地状态。