Space Gravity issues, need help

Started by
12 comments, last by haphazardlynamed 16 years, 2 months ago
Hello, I am attempting to make a 3d space game with spaceships and all that. I have it set up to load models but now I am trying to make the space ship have the "space" feel. I want it to when user presses a key, it goes forward pretty fast then slowly slows down like a ship would do. I don't want instant stops This is what I have so far. void Keyboard(unsigned char key, int x, int y) { #pragma unused (x, y) bool flag = false; rads=roty*(PI/180.0f); //convert degrees to radians cosa=cos(rads); sina=sin(rads); switch(key) { case 'w'://Move forward velx += cosa *10; velz += sina*10; } thePlayer.x += velx; thePlayer.z += velz; glutPostRedisplay(); } one of my problems I think is that, this function gets called only when a user presses the key. maybe? velx and vely are the velociy of the player, an thePlayer is the actual player movement. Everytime I press "W" it goes forward but instantly stops. Let me know what I am doing wrong and if you need any more info let me know. Thanks, Nahid569
Advertisement
You should try some simple Euler integration instead, or similar.

Perhaps a bit technical, but: http://en.wikipedia.org/wiki/Euler_integration

The gist of it is this: instead of specifying the acceleration directly, you specify the force of the rockets/thrusters. This is exactly what would happen to a normal spaceship, as the rockets apply a force to the ship. This force "turns" into acceleration, and the acceleration makes the velocity change.

So, as long as the player depresses the "forward" key, have FengineX set to cos(rads)*EnginePower, similar for FengineY. If the key is not pressed, set them to zero.

Then, when updating the physics, first accumulate all forces. Since you want it to slowly halt, you'll want to introduce drag (albeit a bit unrealistic in outer space). A simple way to approximate this is to introduce a force which is proportional to the velocity, but "works" in the opposite direction. So

void AccumulateForces() {
ForceX = ForceY = 0;

ForceX += FengineX;
// compute drag
float dragX = -velX * dragCoefficient;
ForceX += dragX;

.. similar for Y

}

dragCoefficient specifies how "aerodynamical" the ship is. Try with zero first to see that it moves correctly, then try low values (ie 0.01) and adjust.

Next you want to perform the integration. For this you need to select a suitable "timestep" which is basically how large steps you take, and is typically around 30-60fps. Setting this as constant will make it depend on framerate, you can learn about how to fix that later.

float dt = 1.f / 30.f;

The physics. You can read more about the details here: http://www.gaffer.org/game-physics/integration-basics/

void TimeStep(float dt) {

AccumulateForces();

float aX = ForceX * inv_mass;
float aY = ForceY * inv_mass;

velX += dt * aX;
velY += dt * aY;

posX += dt * velX;
posY += dt * velY;
}

where inv_mass = 1 / mass of the ship.

Now, simply call TimeStep(dt) inside your game loop, and use posX and posY for the space ship position.

Think that should be it, though I haven't tested it :)
If I understand you correctly, then what you have is this:
- while 'W' key is held down, ship moves forward
- as soon as 'W' key is released, ship stops immediately.

You are exactly correct that your main problem is that the code gets called only when the user presses a key.

What you instead need is to finagle some sort of main update loop that is always running, where on each iteration of the loop, you update the ship's position and redraw the frame. Once you have this sort of pattern in place, your life will be much easier. Now, I forget exactly how to do that in GLUT (I use SDL instead, which I recommend as a superior library to handle windowing and input, while still allowing you to use OpenGL), but read your documentation and I'm sure you can find a way.

Once that is in place, you can start taking Lord Crc's advice. Basically, you want a level of indirection -- instead of a key being down directly controlling the velocity (which in turn directly affects the ship's position), you want the key being down to control acceleration, which will affect the velocity much in the same way that velocity, in turn, affects position. In this manner, the key being held down will indirectly affect position. There'll then be room for you to apply some filters in between, the main one being applying a dampening effect of some sort to slow the ship's velocity down when the key isn't being held. (You probably also want to cap the speed at some maximum velocity also.)

I hope that helps -- good luck!
"The world of private Banking especially is fraught withhuge rewards for those who sit upon certain chairs and oversee certainportfolios." -spam email
The property you're describing is related to inertia and the conservation of momentum. Newton's first law sums all of this up well.

Viscosity is the property of a material to disperse the momentum of objects in contact with it. The higher the viscosity, the higher the rate of slow down. The ship should not slow down at all in space, since the vacuum of space is (practically) non-viscous. Since the momentum is not transferred from the ship to the vacuum, the ship must maintain the same velocity in order to ensure the conservation of momentum.
Hey guys THANKS alot!

Those are gread ideas lord and I will use that but first I need to get a way to make a function that runs always. I do not have an idea how to do that. I was thinking of putting the entire movement thing in MAIN function because that is always running but I do not know how to do the keyboard thing outside of Keyboard function.

Is there a better way? Let me know
The heart and soul of any 3D game is a Message loop. This is just an infinite loop that breaks only if the WM_QUIT message is posted to the window. You should handle your main logic updates in that loop and then your rendering functions.
Quote:Original post by nahid569
Hey guys THANKS alot!

Those are gread ideas lord and I will use that but first I need to get a way to make a function that runs always. I do not have an idea how to do that. I was thinking of putting the entire movement thing in MAIN function because that is always running but I do not know how to do the keyboard thing outside of Keyboard function.

Is there a better way? Let me know


There is. Do a google search for "glut main loop" and you'll find a few pages describing things to try. You just need to register some sort of idle function or main loop, and that should be enough. You can still have a distinct Keyboard function that works the way it does -- and you can just communicate messages from Keyboard to your main loop function by way of...heck, even a global variable just to get things working (but at some point that should become some sort of formalized message loop). Really, I'm sure GLUT has some framework for this in place already...it's just a matter of searching through documentation to find exactly what it is, and then get that working.
"The world of private Banking especially is fraught withhuge rewards for those who sit upon certain chairs and oversee certainportfolios." -spam email
Quote:Original post by nahid569
I want it to when user presses a key, it goes forward pretty fast then slowly slows down like a ship would do

Er, a space ship wouldn't do that. What would make it slow down?
(That is assuming you meant spaceship in the above. If 'ship' refers to an actual sailing ship, it would slow down, yes)
just put something like this
if(currentkeyboardstate.IsKeyDown(Keys.W)){ship.x.velocity = ship.x.velocity + shipscceleration;}if (paused = false){ship.x.velocity = ship.x.velocity - slowdown;}


something like that. Oh, and stuff doesn't slow down in space( only in sci-fi films)
Let he who will move the world first move himself--Socrates
Quote:Original post by Spoonbender
Quote:Original post by nahid569
I want it to when user presses a key, it goes forward pretty fast then slowly slows down like a ship would do

Er, a space ship wouldn't do that. What would make it slow down?
(That is assuming you meant spaceship in the above. If 'ship' refers to an actual sailing ship, it would slow down, yes)


Was about to post the same. On earth what makes things slow down is various forms of friction: air resistance, ground friction, friction of moving parts.

In space there is a pretty good vacuum meaning there are none of these frictional forces. In space, a ship that's moving will effectively keep moving forever until it slows itself down with it's engines by producing a trust in the opposite direction. (I say "effectively" because space is not a perfect vacuum so over galactic distances there would perhaps be enough 'air resistance' to eventually slow you down)

-me

This topic is closed to new replies.

Advertisement