游戏开发 - 在跳跃期间遇到AABB碰撞检测问题。

我的碰撞检测通过获取矩形之间的交集并反转效果来工作。这是在每帧期间发生的。它运行得很好,除非玩家坐在角落里并跳跃。偶尔情况下,垂直交集大于水平交集,这使我的玩家沿着平台的侧面滑落。有什么建议吗?

该段代码用于检测玩家和平台之间的碰撞,并根据碰撞位置反转效果。其中可能出现的缺陷是在玩家站在平台角落并进行跳跃时,垂直交集可能大于水平交集,从而导致玩家沿着平台的侧面滑落。

点赞
用户5597039
用户5597039

很难从短片中确定,但我认为问题是由于检查最小交叉点而不是检查对象速度方向的交叉点导致的。您可以尝试这样做,以取代smallestBoundary循环:

local boundary = nil
if (player.velocity.y > 0) then
  boundary = topBoundary
elseif (player.velocity.y < 0) then
  boundary = bottomBoundary
elseif (player.velocity.x > 0) then
  boundary = rightBoundary
elseif (player.velocity.x < 0) then
  boundary = leftBoundary
end

当然,这不是最为强健的方法。您还可以尝试将这个方法和另一个方法相结合,用以下内容替换smallestBoundary循环:

    local yMod = math.abs(player.velocity.y)
    local xMod = math.abs(player.velocity.x)
    local topMod = player.velocity.y > 0 and yMod or 1
    local bottomMod = player.velocity.y < 0 and yMod or 1
    local rightMod = player.velocity.x > 0 and xMod or 1
    local leftMod = player.velocity.x < 0 and xMod or 1
    local boundaries = {
        bottom = (bottomMod / MAX_VELOCITY) * bottomBoundary,
        top = (topMod / MAX_VELOCITY) * topBoundary,
        right = (rightMod / MAX_VELOCITY) * rightBoundary,
        left = (leftMod / MAX_VELOCITY) * leftBoundary
    }

    for direction, boundary in pairs(boundaries) do
        if not smallestBoundary then
            smallestBoundary = boundary
            smallestDist = direction
        end

        if smallestBoundary > boundary then
            smallestBoundary = boundary
            smallestDist = direction
        end
    end

这将做到现在正在做的事情,但将根据它们的速度在该方向上调整界限的大小(仅在比较上下文中)。因此,如果您向x移动并具有-5,并且向y移动并具有-10,那么在y平面中的向下碰撞将具有左侧碰撞的两倍重量。当然,还有另一种选择,即在每个碰撞平面中调整玩家:

    if bottomBoundary > 0 then
        player.desiredPos:add(diffX, -bottomBoundary)
        player.velocity.y = 0
        player.onGround = true
    end
    if topBoundary > 0 then
        player.velocity.y = 250
        player.desiredPos:add(0, topBoundary)
    end
    if rightBoundary > 0 then
        player.desiredPos:add(-rightBoundary, 0)
    end
    if leftBoundary > 0 then
        player.desiredPos:add(leftBoundary, 0)
    end

这最后一种方法是最有意义的,但是您似乎无法均匀处理所有方向上的碰撞,因此可能不适合您的架构。

请记住,我不熟悉您正在使用的框架,因此此代码可能不会立即起作用。此外,此帖子假定+y为上,-y为下,+x为右,-x为左。

2015-12-15 22:26:53