# 2D physics collision/gravity problem?

I'm using Love2D and my own physics engine to create a 2D platformer. Y collision works fine, but X collision... well, it's a bit buggy. When I move off of a small platform I've created, I fall but it is a lot slower than what my gravity is set to. Here's my code for collision:

function world.collisionCheck(o)
for k, v in pairs(world.objects) do
if v ~= o then
if v.Type == "Rectangle" and o.Type == "Rectangle" then
if o.Position.Y + (o.Size.Y / 2) > v.Position.Y - (v.Size.Y / 2) then o.Velocity.Y = 0; o.onGround = true; end
if not (o.Position.X + (o.Size.X / 2) > v.Position.X and o.Position.X - (o.Size.X / 2) < v.Position.X + (v.Size.X)) then o.onGround = false; end --right left
end
end
end
end


As you can see, it's pretty bad. The code for the actual physics (gravity, movement, etc.) is a bit better:

function world.update(t)
for k, v in pairs(world.objects) do
if v.Static ~= true then
v.Position.X = v.Position.X + v.Velocity.X
if v.onGround == false then if v.Velocity.Y < world.Gravity then v.Velocity.Y = v.Velocity.Y + world.Gravity * t end end
v.Position.X = v.Position.X + v.Velocity.X * world.Meter
v.Position.Y = v.Position.Y + v.Velocity.Y * world.Meter
v.Velocity.X = v.Velocity.X * world.Friction
world.collisionCheck(v)
end
end
end


However, it could still use some work. Whenever I step off of a 150 pixel by 15 pixel platform, I fall a lot slower than 9.8 meters per second. My meters are set to two pixels, and I'm falling at about a meter per second, which is much slower than the expected ~20 pixels per second I get while still on the platform. Everything I've tried doesn't seem to fix it; there's no problem in the movement code, and nothing I change in the collision code seems to fix it. Is there some silly problem I've overlooked?

EDIT: Okay, so I implemented a small fix which somewhat solves my problem. I modified the collision code so that it checks if it is below what is being tested for collision, and it seems to accelerate as normal when the top of the object is below the object being collided with, and vice versa. Am I correct in assuming I just need to add something to detect if the x-value is in the correct range, too?

Regarding your gravitation/acceleration physics, here's your code again with a bit of reformatting:

function world.update(t)
for k, v in pairs(world.objects) do
if v.Static ~= true then
v.Position.X = v.Position.X + v.Velocity.X
if v.onGround == false then
if v.Velocity.Y < world.Gravity then
v.Velocity.Y = v.Velocity.Y + world.Gravity * t
end
end
v.Position.X = v.Position.X + v.Velocity.X * world.Meter
v.Position.Y = v.Position.Y + v.Velocity.Y * world.Meter
v.Velocity.X = v.Velocity.X * world.Friction
world.collisionCheck(v)
end
end
end


I see a few problems here:

• v.Position.X = v.Position.X + v.Velocity.X is missing a "t" behind the velocity.

• You compare v.Velocity.Y < world.Gravity which might be what you want "number-wise", but it's not physical. A velocity is not an acceleration (which gravity is), and thus cannot be compared with gravity. You can introduce a steadyStateVelocity, though, which seems to be the intention of your code.

• Simply "cutting off" the velocity while falling is probably not a good idea either. You can introduce friction here just like for v.Velocity.X (world.Friction). Should friction actually a property of "world"? (imho it should not, even in games)

• Your modeling of friction is a bit odd. Usually friction is modeled as F = k*v, with a friction force F acting on a body, a drag coefficient k and the velocity v. This is just one of a few forces acting on a body, at least gravity should be included as well. You can adjust k to be velocity dependent, which is pretty close to what is done in fluid mechanics (simplified). The sign of k should be negative in order to result in drag, or simply take -k if you want to use positive values for k.