Page 1 of 1

Platformer friction

Posted: Fri Sep 04, 2015 8:16 am
by HighwireAct
Hey guys,

I've been having a lot of problems lately conceptualizing platformer friction. I've watched several Khan Academy videos to refresh my knowledge on the subject, and I have a pretty good fundamental grasp on friction, but my problem is in "gamifying" it, if that makes any sense. Since I'm not going for a full-on physics engine for my game, I don't particularly need to store/use things like force or mass for player movement.

I know I'd like to have some friction vector slowing the player's acceleration to an eventual, constant velocity, but I can't figure out a way to implement that. I'm sure there's an obvious answer somewhere, but I've been stewing over this a while to no avail. If someone could push me in the right direction, I'd very much appreciate it!

Re: Platformer friction

Posted: Fri Sep 04, 2015 11:20 am
by Ulydev

Code: Select all

if not moving and grounded then velocity = velocity*.99 end

Re: Platformer friction

Posted: Fri Sep 04, 2015 11:51 am
by ivan
First off I have to say that there is a difference between "friction" and "damping".
Friction causes loss of velocity when the edges/surfaces of two objects are touching.
Damping decreases the velocity of one object over time.
Ulydev's example looks more like damping rather than friction.
To simulate damping, I like the forumula:

Code: Select all

velocity = velocity / (1 + damping*dt)
Where damping is a coefficient between 0 to infinity.

Friction on the other hand is a lot more complicated.
A while ago, I wrote a short tutorial
on how to simulate friction in a custom collision system.
The technique involves taking the velocity of an object during a collision,
then splitting that velocity into penetration and tangent components.
Friction acts on the tangent axis, perpendicular to the collision normal.

Re: Platformer friction

Posted: Fri Sep 04, 2015 12:33 pm
by veethree
Here's a my standard implementation of friction

Code: Select all

local f = self.friction
if not self.onGround then f = self.airResistance end
if self.xVel > 0 then
	self.xVel = self.xVel - f * dt
	if self.xVel < 0 then self.xVel = 0 end
else
	self.xVel = self.xVel + f * dt
	if self.xVel > 0 then self.xVel = 0 end
end
self.moving = false
Not the cleanest implementation but it works pretty well. It's also simpler than ivan's, and presumably less realistic.


I attached a .love of the game that's from below if you want to look at it in context. The code is in src/entity/player.lua

Re: Platformer friction

Posted: Fri Sep 04, 2015 8:55 pm
by NightKawata

Code: Select all

    		
            -- Sometimes there's a point where we all gotta stop
            if self.frictionEnabled then
    			self.velocity.x = self.velocity.x * (1 - math.min(self.friction*dt,1))
    			if math.abs(self.velocity.x) <= self.stoppingVelocity then self.velocity.x = 0 end
            end
I use a frictionEnabled check for specific armors and the like (or to disable that when you're being knocked back), then the next line's probably as simple as it'll ever get, heh. Replacing "self.velocity.x" with any x velocity variable also works, and honestly, I don't know why I'm using vectors, either.

The last line just makes sure I have a clean 0 velocity, because it will occasionally not be 0 for a small amount of time. You may not need it in most cases, but I remember a use case back in Metanet Hunter: REMIX where I did indeed need that call. I usually set the stoppingVelocity to like 10 or something, so it's not like you'll quite notice 10 jumping to 0 very easily.

But yeah, that's the easiest way to go ahead and try it out. I call it when you're not holding left or right, if that makes any difference to you. Calling it if you're not will make it so you can't even move (that stopping call will prevent movement), so should you need to call this all the time, you can just toss that and be on your way! But I've had no significant problems calling it when you're not holding left/right.

Oh, this also doesn't cover air friction. I've never quite cared about that, no matter how realistic it is. We're looking for fun, not ultra-realism! Hi Grand Theft Auto 4!

Hope this helps! inb4 people bash my code!

Re: Platformer friction

Posted: Sat Sep 05, 2015 10:47 am
by airstruck
ivan wrote:

Code: Select all

velocity = velocity / (1 + damping*dt)
Where damping is a coefficient between 0 to infinity.
I was using something simlar to that, but switched to this:

Code: Select all

((1 - damping) ^ dt) * velocity
Here damping is a value from 0 to 1, it's more expensive but the meaning of the value is clearer (it lies on a scale from "don't slow down at all" to "stop immediately").

Re: Platformer friction

Posted: Tue Sep 15, 2015 5:25 pm
by HighwireAct
Sorry for replying so late! Thank you all for the responses. It seems like a system of acceleration and damping rather than straight up friction would be much better-suited for this game.