Gravity with air-time, acceleration and speed gaining
Asked Answered
M

3

9



I am trying to accomplish a gravity, where airtime is included, and also acceleration.
I have tried using usual gravity, which looks something like this:

velocity += gravity * dt;
position += velocity * dt;


This would probably work good enough for a normal platformer game, but I am trying to make a game inspired by "The helicopter game", where you have to navigate through a tunnel, without touching the walls.

what I want to do different, is that I want to be able to save up speed on the way down, which will be used on the way up again, so I will have some acceleration at the beginning.
I also want some kind of airtime, so when you hit the top it would not force you down as fast as It would, if I had used the gravity from the code sample.

This image illustrates the curve I would like to have:
Link to curve

Please note that the whole controlling is done by one key, so for example you would fly up if you held down space, and dive if you released it.
The character also never moves left or right, since it will have a static X position on the screen, so vectors can't be used.

I have spent hours trying to make it work, but with no success. I have also tried searching on the internet, but without any luck.

The game "Whale Trails" got the gravity I kind of want.
Here is a link for a video of the game: http://www.youtube.com/watch?v=5OQ0OWcuDJs

I'm not that big of a physics guy, so it would be cool if you could give an example of the actual code
I hope anyone can help me figure this out.

Mouthy answered 24/11, 2011 at 23:59 Comment(5)
Not a bad question, but showing some code that illustrates what you've tried - and a description of how it doesn't work - would help you get answers. :)Sickert
I'm not a physics guy aswell, but my guess is that you need to dig a bit deeper into physics to accomplish what you want. So i think the physics of airplanes should you get going into the general direction. Maybe this helps you a bit at least finding the correct words to look for solutions to your problem. Also in the newest Batman - Arkham City Game, you have a similar mechanic, maybe worth checking out.Impracticable
@djacobson it was mostly just random code, since I had no idea of where to go, so it woulden't do any good :)Mouthy
@Impracticable You are probably right, but it would be nice if there was some code for it already ;)Mouthy
In the Whale Trails game the horizontal velocity appears to change even though the whale stays in the same position on the screen. The screen scrolling speeds up and slows down. Seems like you will need to use a 2D vector to duplicate this behavior.Lepore
C
4

Gravity is the force that pulls objects down. Your player is the force that pulls objects up. Accordingly your code must be:

if(keyPressed) {
  velocity += POWER_OF_PLAYER;
}

velocity += G;
position += velocity;

This is enough to create a curve like you illustrated. Of course POWER_OF_PLAYER must be of a different sign and the absolute value must be greater to make this work.

G = -9.81
POWER_OF_PLAYER = 20

Saving power is then a simple check.

if(keyPressed) {
  if(powerSaved > 0) {
    velocity += POWER_OF_PLAYER;
    powerSaved -= SOMETHING;
  }
} else if (velocity >= SOME_MINIMUM_SPEED_BEFORE_GETTING_POWER) {
  powerSaved += SOMETHING;
}

SOME_MINIMUM_SPEED_BEFORE_GETTING_POWER should be something less or equal 0.

P.S. I assumed your Y axis starts at ground and shoots into the sky. Signs put accordingly.

Chevaldefrise answered 25/11, 2011 at 0:36 Comment(5)
I'm pretty sure i have tried this out, But I'll give it a go with your code and see if it works :)Mouthy
This is the standard formula, the physics of the game is different.Westnorthwest
Your math is wrong. Gravity is a force, i.e. it has units mass*acceleration, while velocity has units of distance over time, so setting velocity += GRAVITY is fundamentally incorrect.Dougall
@Dougall The variable would have to be named G or STRENGTH_OF_THE_GRAVITATIONAL_FIELD (which is mass-independent and equivalent to an object's acceleration by the gravity) to fix that or we have to assume that all masses in that system are of 1. Still that doesn't invalidate the rest of the answer.Chevaldefrise
Yes, assuming that mass is 1 kg, it's close. You still need to multiply G by a time increment to get the units correct, same thing with Power_Of_Player, provided it also is a force.Dougall
R
0

It looks like the velocity of the fish is constant.

Try the following:

velocity is fixed and should not change (unless the fish eats a speed power-up). angle = 0 is equivalent to level flight.

angle -= gravity * dt;
if (angle < - Math.PI / 2) {
  angle = Math.PI / 2;
}
if (keyPressed) { 
  angle += power * dt;
}

if (angle < - Math.PI / 2) {
  // Stop the player from doing a looping
  angle = - Math.PI / 2;
}
if (angle > Math.PI / 2) {
  // Stop the player from doing an inverted looping
  angle = Math.PI / 2;
}
// Move the fish (vertical component of velocity)
position += velocity * dt * Math.sin(angle);
// Move the background (horizontal component of velocity)
background_position -= velocity * dt * Math.sin(angle);
Ruthenian answered 25/11, 2011 at 13:58 Comment(2)
When using your code the player is just going straigth, unless when the key is pressed, it will go slightly down.Mouthy
Try to make the changes in angle smaller - angle -= gravity * dt / 100.0; and angle += power * dt / 100.0;Westnorthwest
L
0

It sounds like incorporating 'lift' that is based on horizontal speed and have the button press trigger a 'noseup' movement would work sufficiently well.

So lift would be some constant k multiplied by the horizontal speed Vx and vertical speed Vy would be the difference of gravity and lift times the change in time dt

lift = k * Vx
Vy += ( lift - gravity ) * dt

def noseup
  k = 0.01 #some small chunk
  dx = k * Vx
  dy = k * Vy
  Vx -= dy
  Vy += dx

When the plane (or whatever) noses up it basically lowers the velocity on one axis while increasing it on the other.

Probably wouldn't be a bad idea to throw drag in there somewhere as well now that I think about it, would have to be dependent on the absolute velocity V = ( Vx**2 + Vy**2 )**0.5...and weight is a better word than gravity in this case (less confusing, units wise) but it works I guess.

Not exactly "physics" but a close approximation that should work fairly well. Play around with the values of k and see if you can make it do what you want.

BTW sorry for the uber crappy psuedocode :-P

Liveryman answered 26/11, 2011 at 4:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.