2015-12-15 3 views
0

Мое обнаружение столкновений работает, получая пересечение между прямоугольниками и обращая эффект. Это происходит во время каждого кадра. Он отлично работает, за исключением случая, когда игрок сидит на вершине угла и прыгает. время от времени вертикальное пересечение больше горизонтального пересечения, которое заставляет игрока скользить вниз по боку платформы. Какие-либо предложения?Game Dev - Проблемы с обнаружением столкновений AABB во время прыжков

enter image description here

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

Либо обновление, чтобы охватить AABB-столкновения, либо уменьшить максимальную скорость/гравитацию, чтобы вы с меньшей вероятностью могли закрепить геометрию. –

ответ

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 осталось.

+0

благодарит за код. я пытался что-то сделать со скоростью .. но не мог понять, как использовать его в сочетании с моими границами. я посмотрю на это и попробую позже. – hamobi

+0

wouldnt topMod и т. Д. Возвращать логическое значение? может быть, я читаю это неправильно? вы пишете это в виде тройного оператора? – hamobi

+0

'local topMod = player.velocity.y> 0 и yMod или 1' говорит' local topMod'', если player.velocity.y> 0 then'' topMod = yMod' else'' topMod = 1' 'end'. Это оператор inline if для назначения. –

Смежные вопросы