Platformer friction

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
HighwireAct
Prole
Posts: 4
Joined: Sat Aug 15, 2015 2:12 am

Platformer friction

Post 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!
User avatar
Ulydev
Party member
Posts: 445
Joined: Mon Nov 10, 2014 10:46 pm
Location: Paris
Contact:

Re: Platformer friction

Post by Ulydev »

Code: Select all

if not moving and grounded then velocity = velocity*.99 end
Last edited by Ulydev on Fri Sep 04, 2015 4:16 pm, edited 1 time in total.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Platformer friction

Post 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.
User avatar
veethree
Inner party member
Posts: 875
Joined: Sat Dec 10, 2011 7:18 pm

Re: Platformer friction

Post 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
Attachments
Platformer.love
(18.65 KiB) Downloaded 128 times
User avatar
NightKawata
Party member
Posts: 294
Joined: Tue Jan 01, 2013 9:18 pm
Location: Cyberspace, Room 6502
Contact:

Re: Platformer friction

Post 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!
"I view Python for game usage about the same as going fishing with a stick of dynamite. It will do the job but it's big, noisy, you'll probably get soaking wet and you've still got to get the damn fish out of the water." -taylor
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Platformer friction

Post 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").
HighwireAct
Prole
Posts: 4
Joined: Sat Aug 15, 2015 2:12 am

Re: Platformer friction

Post 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.
Post Reply

Who is online

Users browsing this forum: Majestic-12 [Bot] and 3 guests