calculation to change a helicopter's vertical position, adjusted with gravity

This is my very first question, so don't be too hard on me :)

I am a beginner programmer, and I am working on the typical helicopter game, working with a one-button push:

When the button is pushed, the helicopter ascends, starting ascending slowly, accelerating upwards. When the button is released, the upward acceleration slows down, then the helicopter starts falling.

This calculation would run in a loop. As a result, I would have to get a floating point number between 0 and 1, which would correlate with the vertical position of the helicopter on screen.

What I have so far is very wrong, but I post it here anyway:

newPosition = (oldPosition * gravity) + (acceleration * sensitivity)

where gravity and sensitivity are constant. Acceleration is the length of the button push, which becomes 0, as soon as the button is released.

Of course, this is wrong, because this way the helicopter descends quickly first, then slows down as it gets closer to the ground (to value 0).

Any help would be greatly appreciated -- as you can see, I am not a math genius. It would also be great to get some help on how to approach these calculations, so I could come up with similar calculations in the future.

-

Ah, the old helicopter game. No sweat, it's actually very simple. But because you're modelling acceleration, you really do want a variable which represents velocity. Then you can just do this:

every frame {

if(mouse down) {
velocity += [gravity constant];
} else {
velocity -= [thrust constant];
}

position += velocity;

}


Without a velocity variable, it's very tricky to get the effect you want.

-

Keep in mind the following:

Rate of change of distance (or in you case, position) is velocity.

Rate of change of velocity is acceleration.

Acceleration is proportional to the net force acting on the object

So assuming that the button push gives a constant thrust (or force), we can assume your acceleration is constant, while the button is being pushed. When the button is released, the acceleration is due to gravity, which again gives a constant acceleration (different from previous, though).

The following gives us the relation of distance and constant acceleration (for a derivation, see link at the end of the answer)

$$x = ut + \frac{at^2}{2}$$

where $u$ was the initial velocity and $t$ is the total time elapsed.

Thus if you want to calculate new position from old, you need to use

$$\Delta x = (u + at)\times \Delta t$$

(Keep in mind the appropriate signs)

where $\Delta t$ is time change (which is assumed to be very small), $\Delta x$ is the position change and $t$ is the total time.

Note, if the acceleration changes abruptly (like losing thrust because of release of button), you need to reset your $t$ and $u$. To reset your $u$, you would need to keep track of your velocity, whose change is given by

$$\Delta v = a \Delta t$$

Note: It could so happen that your $\Delta t$ is not small enough (a possible problem with game loops), in which case you could try using the general formulae

$$x = ut + \frac{at^2}{2}, \ \ v = u + at$$

(Again, keep in mind the appropriate signs).

In general, you can approach these problems by using calculus.

Hope that helps.

-

I'm not sure I completely understood your approach, but here is how I would tackle it. A uniform acceleration $a$ in one dimension implies the following type of movement for an object:

$$x(t)=x_0+v_0 \cdot (t-t_0) + \frac{1}{2} \cdot a \cdot (t-t_0)^2$$

where $x_0$ is the initial height, $v_0$ the initial velocity and $t_0$ is the initial time. The equation then gives you the position of the object at each instant $t$.

This is all for a constant acceleration though, if you want to make the acceleration dependent on a button push, you can proceed as follows: the equation describing the position of the helicopter is a differential equation

$$\frac{d^2 x}{dt^2} = a(D)$$

$D$ represents a variable that depends on the duration of the button push. If $D=0$ then the acceleration is zero as well, if the duration of the push is different from $0$, you take $a(D)=s\cdot D$ where $s$ is the sensitivity. To make things more realistic, I think you should place an upper bound on the acceleration, so that you can't accelerate indefinitely. But I guess that is easy to program. Now, you just solve the equation, keeping in mind that $D$ will actually be an function of time that is in general not known, but has to be computed each time for each situation. So what you do is solve the problem for small time steps during which it is reasonable to approximate the acceleration as being constant. This will not be perfectly true for the sudden changes from pushing the button to letting go of the button, but if the time intervals are chosen small enough, it should not matter much. But assuming that for short time intervals the acceleration is constant (or uniform) we are back to our very first equation.

So the new position $x_n$is given in terms of the old position $x_o$ as

$$x_n=x_o+v_o \cdot (\Delta t) + \frac{1}{2} \cdot a(D) \cdot (\Delta t)^2$$

If you don't want to keep track of velocities, you can also use the fact that the velocity of the previous step is

$$v_o = \frac{x_o-x_{oo}}{\Delta t}$$

but this means that you have to keep track of the old position and the position one time step older $x_{oo}$.

EDIT: One final comment about gravity. When your helicopter is just hovering in the air, gravity is certainly acting, but the pull is compensated by the lift of the rotor blades. So the upward acceleration due to the rotorblades is equal in magnitude but opposite in sign to the gravitational acceleration. There are several ways you can account for this in your formula. Either you consider $a(D)$ to be the acceleration after gravity has already been substracted, which means that when there is no button push, the helicopter will just hover in place.

Either you want $a(D)$ to represent the acceleration produced by the rotorblades, and then, you have to substract the gravitation from $a(D)$ in the formulas above. You also have to adapt the formula for the link between button push and acceleration. Probably you want the helicopter to hover when nothing happens, so the formula will be $a(D)=g+s\cdot D$. But as you can see, the net effect will be the same as in the former suggestion. It gets more tricky though if we want to add things like starting up the helicopter from the ground, etc... but everything can in principle be computed by adapting the function $a(D)$.

-
Thank you, this looks perfect! Let me get my head around it and put it into the code -- then I will get back to you if it worked. – Antal Jan 19 '11 at 13:12
OK, I just realized I overlooked a little detail. When you stop pushing the button, acceleration will indeed instantly drop to zero with the formula I provided, but speed won't. This means that the helicopter will not just stay in place but continue to go up at constant speed. In reality, air resistance will decrease your speed. You can add this effect in your formula by making $a$ dependent on speed as well. $a(D,v)=s\cdot D - r \cdot v$, where $r$ would be a resistance coefficient. – Raskolnikov Jan 19 '11 at 13:46
Maybe you can pay a visit to the Game development stack, I wouldn't be surprised they already discussed the problem there. I remember seeing a link with details of how Sonic's movement parameters are programmed in the Sonic games. – Raskolnikov Jan 19 '11 at 13:55