Acceleration and Friction in 2D games

Hello, me again :smile: !
Iā€™m building my own tiny physic engin for my 2D game engin and I want to implement acceleration and friction on my entities wich have velocity. I find a good equation here : https://stackoverflow.com/questions/667034/simple-physics-based-movement

For people who dont want to click, there is the equation :

velocity += acceleration - friction*velocity

But there is a problem :

Letā€™s say I want to calculate the gravity on my entity (Acceleration = 9.83), so i calculate the velocity Y with the equation, and lets say i have 0.5f of friction. So each game step, the following code is applied to my entity:

velocityY += 9.83f - 0.5f * velocityY

So we have this table of velocity for each step :

Step n : velocityY
1 : 9.83
2 : 14.745
3 : 17.2025
4 : 18.43125
5 : 19.045625
6 : 19.3528
7 : 19.5064

And now, as you can see, at the step 4 we have our velocity which increase very slowly and never pass 20.
I know why it do that, its because :
when the half of the velocity reach near of the half of the gravity (9.83), the friction*velocity is almost as much as the gravity.

So I need help maybe to change the equation or improve it !

Thanks you !

Thatā€™s how it should work. Thereā€™s always some sort of maximum speed because of friction. If you were to jump out of a plane, you wonā€™t keep accelerating until you hit the ground, youā€™ll get to some maximum speed where air friction counteracts your acceleration due to gravity. But of course, realism isnā€™t always what you want in game physics!

One thing you can do is not apply friction when thereā€™s some external acceleration happening. E.g. when you press the right arrow key, your character accelerates to the right. Only when the key is released you start applying friction to reduce velocity. You may still want to clamp velocity to some maximum value in this case, to prevent very high speeds making your character clip through walls and whatnot.
If you still want to apply some friction while accelerating, I recommend just playing around with the equation until it feels right, for example by using velocityY += 9.83f - 0.5 * System.Math.Sqrt(velocityY) or taking velocityY to some other power to change the effect the current speed has on friction.

1 Like

ok i understand much better nox thanks a lot ! I think im gona stay on this. Thanks you !

1 Like

You can try it in a tall glass of oil, releasing a little ball of lead will keep falling at its max speed to the end of the glass. (I did it with my nephew 4 days ago, explaining her physics problem to her)

1 Like

Yep, so iā€™m at the same level as your nephew lol

She is a university student, I reassure you, she isnā€™t 8 years old trying to solve a physics problem. :wink:
But it is always better to make real experiences when possible, than just imagine in your head what could happen. Nature do things better than us.

1 Like

Is there a reason you write your own physics? If your goal is educational / writing physics thatā€™s cool, but if your real goal is writing a functioning game I strongly recommend using an external physics lib.

Writing physics is often harder than it looks. even if its for a ā€œsimpleā€ 2d game :slight_smile:

velocity += acceleration - friction * velocity

the above literally saysā€¦

That velocity changes by the addition of a variying acceleration subtracted by the multiplication of friction and the current velocity.

I mean thatā€™s one way to look at it. but that formula can break down if any of the values become greater then 1 and i think it kinda stinks for a game.

Why bother to even reduce Acceleration at all unless this is a physics app. How about instead just say.,

Velocity is Acceleration and Velocity each frame and that velocity is reduced by friction each frame.
Which is just like saying acceleration and velocity are the same thing which they are from at least one point of view, they both re position a object each frame.

v = v + a - f;

You could set a maximum speed limit for velocity (m) and use that against all the values and make the whole thing delimited to your games maximum desired movement speed for objects which can be useful in a game.

Something like.

t = 1 - (v * m) / (m * m);
d = t * (f + a);
v = v + d;

// were
// f is a negative value for friction that works directly as a opposite force against acceleration and neither a or f can exceed m.
// t is a warping factor that reduces the magnitude of both friction and acceleration as total velocity increases.
// d is the resulting distance in relation to the maximum velocity moved

Point is you should define how you want it to work in your game and describe what the values will do and then just write that out in math.

Actually, itā€™s for writing a functioning game but the main goal of this game itā€™s to get experience. So I donā€™t care if I have to reinvent the wheel and it takes 1 year but in this year I would have learned a lot ! (But maybe for my GUI I will use GeonBitUI :wink:)

No, the formula dont break if any values past 1, except for the friction but I take care of that.

In my game, each entity have a ForceList. Its an object wich can calculate the acceleration based on the forces we aplly on the entiy. So in my implementation of acceleration, friction is just a value but in your formula, friction is just another ForceList (if I implemented that in my code). So if I had read this 3 day earlier ā€¦
Thanks you for your help ! I think I will stay on my formula, its close to what I saw in school, so this formula is quite familiar for me. But thanks anyway ! :grin:

Iā€™m a big fan of this physics from Handmade Hero:

acceleration += velocity * -friction
position += (acceleration * 0.5 * time^2) + (velocity * time)
velocity += acceleration * time

To apply input you add to the acceleration, ie.

if (keydown('w'))
{
    acceleration.y -= 500;
}

I didnā€™t watch to check but I think itā€™s explained here https://hero.handmade.network/episode/code/day043#3683

Nice formula, its just basically the original formula position = 1/2*g*t^2.
But in my physics, the velocity must be directly added each frame to calculate collision with the Swept method (https://www.gamedev.net/resources/_/technical/game-programming/swept-aabb-collision-detection-and-response-r3084) :slight_smile:

Yeah I donā€™t actually do ā€œposition +=ā€ I do ā€œvar positionDelta =ā€ and then apply the change in position after collision checking.