Log In  

I have an issue with collision detection when my character is falling, shown in the GIF below:

After a few jumping attempts, the player falls straight through the platform he is meant to land on. This is most likely because the fall rate accelerates, and the player/platform collision boxes aren't connecting. I'm setting the player collision box to a single line at the player's feet, like this:

This is to make it easier to detect if the player jumps through the bottom of a platform and lands on top of it.

Here's how I check for collision:

function plat_collision(o)
 for _,p in pairs(plats) do
  if intersect(p.crect,o.crect) then
   o.y=p.crect.y-8 --this is used to handle jumping through bottom of platforms
   return true
  end
 end
 return false
end

function intersect(rect1,rect2)
 if (rect1.x < rect2.x + rect2.w
 and rect1.x + rect1.w > rect2.x
 and rect1.y < rect2.y + rect2.h
 and rect1.y + rect1.h > rect2.y) then
  return true
 else
  return false
 end
end

And here's the bit in my update function :

if not pl.on_ground then
  --accumulate gravity
  pl.dy+=pl.grav
  --fall
  pl.y+=pl.dy
 end

 if pl.dy>0
 and not pl.on_ground then
  pl.is_falling=true
 else
  pl.is_falling=false
 end

 --if falling check if we have
 --hit a platform
 if pl.is_falling then
  if pl.y>121 then
   --stop player falling through bottom-most platform
   pl.y=115
   pl_landed()
  elseif plat_collision(pl) then
   pl_landed()
  end
 end

 --not falling, test if we are
 --stood on a platform
 if not pl.is_falling
 and not plat_collision(pl) then
  pl.on_ground=false
 end

Anyone have any pointers?

P#81449 2020-09-02 17:37 ( Edited 2020-09-02 20:24)

I'm not sure, but maybe putting a maximum limit to pl.dy value could help. Is that already being done? Because what might be happening (especially considering the bug happens after a few jumping attempts) is that pl.dy continually increases to a value so high that the player "skips" the pixel position in which it would collide with the floor. Another thing that comes to my mind is you could make the collision "box" behave differently depending on the player's jumping direction: jumping up, collision is a line, as you described; falling down, collision is a box, with some padding, to help you avoid such bugs. Anyway, that's what I could think about right now. I hope it helps.

P#81463 2020-09-03 04:03

what I would do is ethier make the hit box for stuff grow slightly in size if your falling faster, or
Like how Super Mario 64 does it check the quarter steps of mario. (so just split the velocitys in 1/4s and test each step (for i=1,4 do player.pos + player.vel/4==(test here) end (or whatever num.)) of them. this is helpful for testing stuff when your player is moving super fast by testing smaller bits.)

P#81464 2020-09-03 04:24 ( Edited 2020-09-03 04:26)

if the player can move faster than 1 tile, one option is to iterate over.
eg:

  • compute number of tiles traversed: flr(velocity.y/height)
  • loop over tiles and perform regular collision checks

Another brute force approach (used for ex in Towefall) is to perform a collision check for each pixels:

  • convert velocity.y to pixels
  • loop over and perform collision
P#81465 2020-09-03 05:44 ( Edited 2020-09-03 05:48)
1

Thanks for all the suggestions guys. All make sense, but I went with profpatonildo's idea of capping pl.dy as it was the quickest to implement. It also has the bonus effect of slowing the fall rate, which looks more realistic in a space scenario.

P#81510 2020-09-04 22:48 ( Edited 2020-09-04 22:50)

Yeah!! :D I'm glad to be helpful!

P#81513 2020-09-05 02:19

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-29 00:14:53 | 0.006s | Q:14