1
$\begingroup$

I know I should have listened to my teacher in physics class but I didn't. I need help on a thing I am trying to do for a game.

I want to be able to calculate Gravity pushing down on a object over a certain amount of time. (I want the object to slow down to a stop and then go back down due to gravity).

I've been looking on the internet and I guess I'm not using the right search terms. So I am hoping that this fine community can help me.

*The object(Player) is only moving upward. The Player is not moving forward or anything. Just Up

Given the initial velocity, how do I compute the motion (position, velocity) of the object as a function of time?

$\endgroup$
5
  • $\begingroup$ You could use $F_g = G\frac{m_1m_2}{r^2}$, Newton's law of universal gravitation. $\endgroup$
    – HDE 226868
    Aug 23, 2014 at 19:09
  • $\begingroup$ It's not clear what your question is. $\endgroup$
    – garyp
    Aug 23, 2014 at 19:11
  • $\begingroup$ Object A is going Upward at 8 speed and I want the object to slow down and drop over time due to gravity. I want to be able to calculate it in code. $\endgroup$ Aug 23, 2014 at 19:13
  • $\begingroup$ You might be looking for Newton's second law, $\vec{F}=m\vec{a}$, where $\vec{a}$ the time derivative of velocity. $\endgroup$
    – fibonatic
    Aug 23, 2014 at 19:46
  • $\begingroup$ search the internet for "projectile motion" $\endgroup$
    – Jim
    Aug 26, 2014 at 19:01

2 Answers 2

2
$\begingroup$

The standard approach in numerical simulations is to do a discrete time stepping. If the motion is limited to the vertical direction, you just need to keep track of vertical position $z$ and vertical velocity $v$ (with positive $v$ denoting upward speeds). Starting with given values for $z$ and $v$ (the initial position and initial velocity) you update the position and velocity after each time step as follows:

$$v_{new}=v_{old}-g\Delta t$$ $$z_{new}=z_{old}+\frac12 (v_{new}+v_{old}) \Delta t$$

Here $g$ represents the gravitational acceleration, and $\Delta t$ the step size used in the time stepping.

More advanced time-stepping schemes exist, but I assume this will suffice for a game simulation.

$\endgroup$
3
  • $\begingroup$ This is more accurate than the time steps I used in my "good enough for gaming" code... $\endgroup$
    – Floris
    Aug 23, 2014 at 19:50
  • $\begingroup$ I hope you don't mind that I have updated the calculation example in my answer to show that your method works better than the one I originally showed - with attribution, of course. $\endgroup$
    – Floris
    Aug 23, 2014 at 20:11
  • 1
    $\begingroup$ @Floris - be my guest! $\endgroup$
    – Johannes
    Aug 23, 2014 at 20:13
1
$\begingroup$

Assuming you are using C code:

#include <stdio.h>
int main(void) {
  float position = 0, velocity = 8, time, timeStep = 0.01;
  float g = 9.8;
  for(time = 0; velocity > -10; time+=timeStep) {
    velocity = velocity - timeStep * g;
    position = position + velocity * timeStep;
    printf("time %f; velocity %f; position %f\n", time, velocity, position);
  }
  return 0;
}

This implements a simple integration of the equations of motion:

$$v = \frac{dx}{dt}\\ a = \frac{dv}{dt}$$

I made the time step very small: you can get away with bigger steps (takes less time). Also I keep the loop going until the velocity has reached a certain downward value: you can use any other criteria (time, position, etc).

UPDATE As Johannes pointed out, you get slightly more accurate results (even when you use larger time steps) when you use the average velocity during a time step to compute the next position. This leads to a small change in code:. Below, I show both the old and the new calculation side by side - as you can see, when the time step is coarser, the new method continues to give good results:

#include <stdio.h>
int main(void) {
  float position = 0, velocity = 8, time, timeStep = 0.1;
  float newposition = 0, oldvelocity;;
  float g = 9.8;
  for(time = 0; velocity > -10; time+=timeStep) {
    oldvelocity = velocity;
    velocity = velocity - timeStep * g;
    position = position + velocity * timeStep;
    newposition = newposition + 0.5*(oldvelocity + velocity) * timeStep;
    printf("time %f; velocity %f; position %f; new position %f\n", time, velocity, position, newposition);
  }
  return 0;
}

Here are the results at time = 1.80 seconds for different time steps:

step = 0.001: velocity -9.650; position -1.494; new position -1.486
step = 0.010: velocity -9.738; position -1.662; new position -1.573
step = 0.100: velocity -10.62; position -3.420; new position -2.489

Finally, the "correct" result from integrating the equations of motion gives

velocity = 8 - 1.8*9.8 = -9.64
position = 0 + 8 * 1.8 - 0.5 * 9.8 * 1.8^2 = -1.4760

As you can see, smaller steps get better results, and using the "new method" (as suggested by Johannes) gets you closer to the true position than the "lazy method" I first proposed.

last update

To implement other forces, you can do something like this:

float acceleration, g=9.8, mass=70, drag = 200;
int hasParachute = 1; // set to 0 if no parachute
int onSupport = 1; // set to 0 if not currently stuck on a rock

force = -g * mass;
if(hasParachute == 1) force -= velocity * drag;
if(onSupport) {
  force = 0;
  velocity = 0;
}
acceleration = force / mass;
newvelocity = velocity + timestep * acceleration

... etc

I hope you can see how you could implement lots of different things that might change the total force on the object and that will change the motion. In this case, the last term (onSupport) sets both velocity and acceleration to zero, meaning that after a small time step it will still be zero - but if you set onSupport = 0 it will once again be able to move. And like this you could have multiple objects doing different things under the influence of gravity, rocket packs, etc. You obviously want to experiment with the drag=200 factor - I just picked a number from thin air, and with a value like 200 you will end up with a terminal velocity of about 3.5 m/s (you would survive that no problem). As you make drag lower, the terminal velocity will be higher (also depends on the mass of the object).

$\endgroup$
11
  • $\begingroup$ Thank you so much this helped a lot. I was using AS3 but I can put it into AS3 easily. Also thank you for being straight forward with the answer, most people just write a lot. $\endgroup$ Aug 23, 2014 at 19:27
  • $\begingroup$ You're welcome. Note that the change in velocity is computed as velocity = velocity minus timeStep * g because I use the convention that up = positive, and gravity acceleration points down (negative). You could have used g = -9.8 and a plus sign... $\endgroup$
    – Floris
    Aug 23, 2014 at 19:29
  • $\begingroup$ Yea AS3 everything is backwards hehe. Thanks again $\endgroup$ Aug 23, 2014 at 19:38
  • $\begingroup$ I got it working thank you :3 .. The only thing I really needed was the velocity but thank you anyways :3 $\endgroup$ Aug 24, 2014 at 2:05
  • 1
    $\begingroup$ Thanks again I can not explain how much you have helped me in the long run :3 Thx I will leave you alone now lol $\endgroup$ Aug 26, 2014 at 21:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.