我的碰撞检测通过获取矩形之间的交叉并反转效果来工作。这是在每一帧中发生的。除了玩家坐在角落顶部并跳跃之外,它的效果很好。每隔一段时间垂直交叉点大于水平交叉点,这使得我的玩家向下滑动到平台的一侧。有什么建议吗?
-- detect initial collision
if mathy.hasCollided(player, platform) then
local playerBoundaries = player:boundaries()
-- list of intersections between platform and player
local bottomBoundary = mathy.bottomBoundary( playerBoundaries, platform )
local topBoundary = mathy.topBoundary( playerBoundaries, platform )
local rightBoundary = mathy.rightBoundary( playerBoundaries, platform )
local leftBoundary = mathy.leftBoundary( playerBoundaries, platform )
local smallestDist = ""
local smallestBoundary
local boundaries = {
bottom = bottomBoundary,
top = topBoundary,
right = rightBoundary,
left = leftBoundary
}
-- get the smallest intersection (thats the side we're probably closest to)
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
-- reverse effects depending on collision location
if smallestDist == "bottom" then
player.desiredPos:add(diffX, -bottomBoundary)
player.velocity.y = 0
player.onGround = true
elseif smallestDist == "top" then
player.velocity.y = 250
player.desiredPos:add(0, topBoundary)
elseif smallestDist == "right" then
player.desiredPos:add(-rightBoundary, 0)
elseif smallestDist == "left" then
player.desiredPos:add(leftBoundary, 0)
end
end
答案 0 :(得分:0)
很难从短片中分辨出来,但我认为问题是检查最小的交叉点而不是检查物体速度方向的交点。您可以尝试这样的代替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
平面中的向下碰撞的重量将是左向碰撞的两倍在x
平面。当然,在每个碰撞平面上总是有另一种调整玩家的选择:
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
已离职。