Use physics. First you'll need to establish this:
1. Hovercraft physics principles
The hovercraft's engines will produce an upwards force of magnitude F, that is opposite in direction to the gravitational force G. The vertical component of the sum of all forces acting on the hovercraft at any given time will be:
sum_of_forces.y = G - F
The First Law of Newton says that force equals mass times acceleration. If the hovercraft's mass is m and the gravitational acceleration is 9.8 [m/s2], then G = 9.8 * m. As for F, its acceleration will be variable, so we'll call it f. Therefore, F = f * m. Replacing G and F in the equation above, we have:
sum_of_forces.y = 9.8 * m - f * m;
sum_of_forces.y = (9.8 - f) * m;
All you care about is the acceleration, which we'll name a:
a.y = sum_of_forces.y / m
a.y = 9.8 - f
The value of a.y should be recalculated every time f changes, or to make things simpler, it should be recalculated on every frame.
The y component of the hovercraft's velocity will be called v.y. Speed changes based on acceleration, and since you're recalculating the acceleration on every frame, you'll do the same with the velocity:
v.y = v.y + a.y;
And consequently the position. But you probably knew that already:
y = y + v.y;
2. Accelerating based on distance to the ground
Now let's get to the fun part. The hovercraft's vertical acceleration must vary according to its distance from the ground, right? So if h is the distance from the hovercraft to the ground, both F (the upwards force opposed to gravity) and f (the upwards acceleration) are functions of it. Therefore, our previous equation F = f * m is now:
F (h) = f (h) * m
In order to keep the hovercraft floating at a constant height IDEAL_HEIGHT from the ground, F must be equal or greater to the magnitude of the gravitational force. Therefore, this must be true:
F (IDEAL_HEIGHT) = 9.8 * m
and since F = f * m, this must be true:
f (IDEAL_HEIGHT) = 9.8
As the hovercraft nears the ground, f should increase. But to be realistic, we'll want to cap f at a maximum value of f_max. And as the hovercraft gets farther away from the ground, it should push less. With that in mind, f(h) must fulfill these two conditions:
f (0) = f_max;
f (IDEAL_HEIGHT) = 9.8;
f (h > IDEAL_HEIGHT) < 9.8;
The simplest possible solution here is to make f (h) a linear function of the form:
f (h) = m * h + b
To find the m and b factors, we do:
m = (9.8 - f_max) / (IDEAL_HEIGHT - 0) = (9.8 - f_max) / IDEAL_HEIGHT
b = f (0) = f_max
Therefore f(h) looks like this:
f (h) = h * (9.8 - f_max) / IDEAL_HEIGHT + f_max
In pseudocode:
function f ( h ) {
return max ( 0, h * (9.8 - f_max) / IDEAL_HEIGHT + f_max );
}
(Note that I'm using the max() function to prevent f from becoming negative.)
3. Putting it all together
So to put it simply, you should just do this on every frame:
// calculate the distance from the hovercraft to the ground
h = hovercraft.y - ground.y;
// calculate the acceleration
a.y = (9.8 - f(h)) * m; // see definition of f() above
// calculate the speed
v.y = v.y + a.y;
// and the position
y = y + v.y;