Gravity Practice 2D

Started by
6 comments, last by DonTzzy 10 years, 9 months ago

Hi, I have been looking at many posts, but none of them really explain what I want to know.

I want to create a "gravity ball" game for practice with gravity so that I can later implement it into my game.

The game consists in a ball dropping with gravity, and you having to click it to push it back up again.

I am not yet concerned with sideways movement as I'd have to calculate angles and stuff, and I only want to focus on gravity itself now.

I have coded this as a gravity function:


acceleration += 9.8;
velocity += acceleration;
y += velocity;

I have however, a series of conceptual problems as I do not truly understand the gravity equation. The following are my questions:

Acceleration is measured as ms^-2, so I would only have to compute this equation every second. This would then make my game change velocity every second and therefore would give an non-smooth effect. How would I go about computing this equation 60 times per second? I think there is an equation for gravity involving time as time an acceleration are related, is there such a thing?

Another thing I can't get my head around is how gravity works when the object is moving upwards. If the downward speed is of, say, 50m/s, and we exert a force that makes it have an upwards speed of 100m/s, how does the formula create the parabola effect needed? Do you reset the timer and the acceleration inside the gravity equation, so that the first second its going upwards it gets a velocity of 90 m/s, and then its velocity keeps decreasing till it flips around and starts falling again? When do I reset the timer?

Please explain how it works, or give me an example of the code used for such an exercise.

Thank you

Advertisement
Here's how people typically make the curve smooth instead of applying changes once per second:



float dt = (time between last frame and this frame measured in seconds);
acceleration = 9.8f; // NOT +=
velocity += acceleration * dt;
position += velocity * dt;
If you want to force your physics to use 60 FPS, you can hardcode:


const float dt = 1.0f / 60;

If an object is on the ground, you have (at least) two choices:
- Disable the gravity code so that the object isn't pulled through the ground
- Resolve the collision with the ground every frame. The object will bounce if you have restitution > 0 or "stick" if you have restitution == 0.

acceleration should be constant.

More like


force = -9.8
velocity += (force / mass) * dt //dt is time passed. For 60 FPS, use 1/60. Basically at smaller timesteps, velocity increases slower
position += velocity * dt //at smaller timesteps position changes slower

This should work for a trivial simulation.

Note that this will not give the exact correct result, especially at large dt, which will cause energy appearing/disappearing from the system. It wont be a problem for trivial stuff, but for lets say orbiting a planet it would make the orbit not stable. To fix it you can use an "integrator" or a smaller timestep (dt) for a more correct result.

o3o

Thanks guys, useful stuff! +1s.

However, can you answer how I would deal with the force upwards when clicking the ball? Does it just change the acceleration, and then I let the formula continue decreasing this upwards velocity till it becomes negative, hence dropping the object again?

For clicking, the simplest way is to just modify the velocity directly *once* per click:

for example in a C# WinForms app:


void OnMouseDown(MouseEventArgs e)
{
   if (/*mouse point is within the ball*/)
      ball.velocity.y = -100.0f;  // I've been assuming that you're using GUI coordinates where negative Y is up.
}

If you use the force based approach (every frame calculate total force acting on the object, like gravity + force from click) you can simply add some amount of force to be applied and it will make the velocity go up.

o3o

Realize you are using 9.8 (obviously m/(s^2) reference), so that means your world is represented in meters. You need to also be able to convert those meters into pixels, so you know where to actually draw on your screen.

So, if you believe your screen is 100 meters tall, you'll need to take the ratio of 100m to the height of your screen before you perform your actual drawing. That way, if a ball starts at the top of the screen, it truly takes the same amount of time to hit the ground as a ball would in our world if it was dropped 100m off the ground.

Or, you can make gravity be whatever you want in your world, and have all units be in pixels to simplify things a bit (maybe 9.8 pixels/(s^2) will work for you).

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)


Please explain how it works, or give me an example of the code used for such an exercise.

http://en.wikipedia.org/wiki/Projectile_motion

This topic is closed to new replies.

Advertisement