0
\$\begingroup\$

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?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

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.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .