Sign in to follow this  

Space Gravity issues, need help

This topic is 3590 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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 :)

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Quote:
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.)


That's the beauty of having a drag force, you get the slowdown when there's no force applied, and the maximum velocity is determined by the drag coefficient and the maximum force (thrust).

Share this post


Link to post
Share on other sites
wow thanks alot you guys are helpful.
I think i get what you guys are saying so i set up a glutIDleFunc and tried it like that but that still causes problems, so im going to try glutMainLoop later today.

About my spaceship, I knaow it should keep going but if that happened then it owuld be cool but then there would be NO way for the user to stop his ship. Maybe I can do that but wouldnt that be a weird game where the user never stops.

Share this post


Link to post
Share on other sites
Quote:
Original post by Palidine
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


If you take the average density of the universe to be 10^-27 kg/m^3, that's roughly one proton per cubic metre.

If you were to travel from one edge of the galaxy to the other (roughly 10^21 metres), and assumed that you would collide with one proton for every metre travelled, it would have the total effect of colliding with a single 1 milligram object. Pitting that against a spaceship of 10^4 or so kg would produce a negligible amount of slow down.

Share this post


Link to post
Share on other sites
Quote:
Original post by nahid569
About my spaceship, I knaow it should keep going but if that happened then it owuld be cool but then there would be NO way for the user to stop his ship. Maybe I can do that but wouldnt that be a weird game where the user never stops.


You slow down by rotating the ship to face backwards and firing the main engine.

Similarly, to make turns, you point the nose of the ship towards the desired center of the turn, then fire the engine and throttle it to provide a centripetal force.


Play Asteroids? or Escape Velocity? they tend to be pretty good examples of this working out pretty well.

Share this post


Link to post
Share on other sites

This topic is 3590 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this