# Gravity: Slow down on ground approach

I'm looking for some math, nothing language dependant.

"Standard" gravity for a character in a 2D game would go something like this:

if player.y > ground.y {
player.velocity.y = player.velocity.y - gravity
}


In the little game I'm implementing I would actually like the gravity to weaken, and the velocity to slow, as the player approaches the ground.

IE: When the character is 100m above ground he should fall faster than when he is 1m above ground. He should land like a feather in a way.

• ok, just multiply it by some height dependant factor. As this is "fictional" gravity it's exact form is ultimately up to you Commented Nov 15, 2014 at 22:57
• Btw, even if gravity goes to zero long before hitting the ground they still won't "fall like a feather". Remember gravity accelerates things, it doesn't directly affect their speed. Possibly you want significant drag near the ground Commented Nov 15, 2014 at 22:58
• @RichardTingle Yes that's what I was thinking, not only do I need to multiple gravity by a height dependant factor, I also need to start applying some "counter-gravity" that's also height dependant. Commented Nov 15, 2014 at 22:59
• If you want a drag type behaviour (and I think you do or you'll have a nasty bounce from anti gravity) you want something along the lines of F=(heightFactor)*(dragFactor)*velocity. The important point is that your force should be proportional to the current velocity Commented Nov 15, 2014 at 23:02
• Pardon my ignorance but in the example you gave would I add F to my current velocity? velocity.y += (heightF)(dragF)velocity? Commented Nov 16, 2014 at 1:11

As you are creating a "fictional force" physics should be our starting point but the exact form can be up to you. My suggestion would be to use a modified drag rather than trying to modify gravity.

## Why you shouldn't use a modified gravity

This is because gravity applies a simple acceleration. This means if an object is rushing towards the ground at 100mph and gets close to the ground so gravity drops to zero it just doesn't get any faster, it doesn't land "light as a feather" as you hope. To slow it down you would have to apply a negative gravity. However; this still wouldn't work nicely because objects that were falling slowly would "bounce" without ever hitting the ground.

## Why you should use a modified drag

What you want to do is apply a force proportional to the velocity of the object. And make that force stronger nearer the ground.

So! What exact form should this force have? My suggestion would be as follows

if (height<heightAtWhichDragStarts){
dragForce=dragCoEfficientAtGroundLevel*(heightAtWhichDragStarts-height)*objectMass*velocity
}else{
dragForce=0
}


Usually drag force would not have mass in it, but I'm assuming you want heavy objects to have just as much "land light as a feather" as light objects so you'll need to apply more force to them. The more lightly you want objects to land the greater dragCoEfficientAtGroundLevel should be. You may want to also only apply this force to objects heading downwards so jumping objects aren't slowed down.

## How to apply this force

If you're using a physics engine apply it as that engine wants it (but be careful to make sure you don't mix up forces and impulses) but if you're "rolling your own" then apply it as follows.

Within your physics step you always want to include the time of that physics step, you'll need that because of how force effects velocity by the formala F=ma and a=changeInVelocity/changeInTime

So:

F=ma
dragForce=mass*changeInVelocity/changeInTime
changeInVelocity=dragForce*changeInTime/mass


Although including the changeInTime in the formula is important to get the physics right its also important for your simulation. If you don't include changeInTime you can get really nasty effects such as if your game slows down (for example because annother program is running) from 60 frames per second to 30 frames per second your physics can actually change which is obviously very bad

• I think the last formula changeInVelocity=dragForce*m*changeInTime doesn't follow the previous line: shouldn't m divide instead of multiply? another idea that suggests it: the dragForce already contains the objectMass multiplying, so here it should divide so they cancel out and you get the same changeInVelocity regardless of mass. Commented Nov 18, 2019 at 13:42
• @jmmut You're right! I've corrected Commented Nov 18, 2019 at 15:54