1
\$\begingroup\$

In my game I have my main object, a jetski, which will dive down into water, when the screen is touched. I managed to code the jetski diving down, with Box2d and some buoyancy forces. But when the jetski is under water, it just rises to the water surface and stays there. Short: the jetski isn't jumping. I thought about applying forces as soon, as the jetski is on the surface. The problem with it is that the force would be a constant force ignoring how deep the jetski was (the deeper the jetski was, the faster it should rise and jump out). Is there any other way of doing this? This is the kind of thing I want: https://www.youtube.com/watch?v=b2t_zMOy5SM

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

I've never tried to get this to work myself, but it seems like you would just need to increase the upward force applied to the jet ski's body as a function of the depth of the jet ski below the "surface" of the water object. The easiest way to get the distance below the surface might be to make a constant variable that describes the height of the water's surface, and then find the distance on the y axis between the jet ski's body and that height. Ex: float upwardForce = someConstantCoefficient * depth.

If a linear formula doesn't get the look that you want, something like float upwardForce = someConstantCoefficient * depth * depth, might.

Altogether it might look something like this:

@Override
public void render(float delta){
    //... other code you may have
    float upwardForce = constantCoefficient * depth * depth;
    //....   
}

and in some code where you handle your inputs...

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    yourBody.applyForceToCenter(0, upwardForce, true);

}

If I were you I would use

Gdx.app.log("", "Upward Force: " + upwardForce);

to figure out what the amount of force is that is being calculated, and adjust the "constantCoefficient" to make the force smaller if that is what is needed. For example if the depth * depth on its own is, say 1000 Newtons, you might want to make the coefficient as 0.1f, so that the force is only 100 Newtons and the jet ski isn't shot upward so fast. Another consideration might be to apply fractions of the upward force for some frames after the button is released, by multiplying the upward force by 1/60, or perhaps even 1/30, or some other fraction that gets the look you want, like this:

float upwardForce = constantCoefficient * depth * depth * 1 / 60;

But a better idea would be to multiply it by the delta between frames so that it isn't buggy in case the frame rate isn't 60 fps, like so:

...depth * depth * delta;

Also be sure to make sure that once the jet ski is no longer touching the water that the force is no longer being applied, other you could get some strange things happening...

I hope that makes sense. If in need for further clarification I might be able to help more :)

\$\endgroup\$
10
  • \$\begingroup\$ and when should I apply the force? right after releasing? and does one single impulse / force do the job? \$\endgroup\$
    – jobr97
    Aug 29, 2015 at 19:50
  • \$\begingroup\$ so I tried applying forces and impulses, but both just lead to a kind of teleporting upwards... Is there a way to accelerate the body in y direction? \$\endgroup\$
    – jobr97
    Aug 29, 2015 at 20:18
  • \$\begingroup\$ I edited my comment to answer your questions. \$\endgroup\$
    – Dibz
    Aug 30, 2015 at 4:29
  • \$\begingroup\$ there youtu.be/DbzeDPTDTjo @dibz \$\endgroup\$
    – jobr97
    Aug 30, 2015 at 12:14
  • \$\begingroup\$ Do you have any drag being applied to the jet ski? Have you tried increasing the coefficient value? It's hard to know without seeing your code, sorry ... \$\endgroup\$
    – Dibz
    Aug 30, 2015 at 16:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .