Page 1 of 1

Time-based Gravity

Posted: Tue Feb 03, 2009 8:56 pm
by Joeyotrevor
Hi everyone,
I've been working on a game engine and I just recently made the movement time based, but I have no idea how to make my gravity time based. I've been using something like this which is called every frame:

Code: Select all

this->gravity++;
	if(this->gravity != 0)
	{
		for(int x = 0; x < abs(this->gravity); x++)
		{
			if(this->gravity > 0)
			{
				this->y -= NV_P_JUMPSPEED;
			}
			if(this->gravity < 0)
			{
				this->y += NV_P_JUMPSPEED;
			}
			if(this->gravity < 0 && this->CheckCollision())
			{
				while(this->CheckCollision())
				{
					this->y -= NV_P_FALLSPEED;
				}
				this->gravity = 0;
				break;
			}
			if(this->gravity > 0 && this->CheckCollision())
			{
				while(this->CheckCollision())
				{
					this->y += NV_P_JUMPSPEED;
				}
				this->gravity = 0;
				break;
			}
		}
	}
and I have no clue how to make it time based. Multiplying the jumpspeed by the target fps divided by the current fps just makes you not jump as high. I've heard about a way to make time based realistic gravity by setting the y velocity to -9.8*time or something but what is "time" and how would I find it?

Re: Time-based Gravity

Posted: Tue Feb 03, 2009 9:21 pm
by LeonBlade
Just have a downwards force acting upon your player.
When you are touching the ground then you stop all velocity moving down.
I'm having some trouble with it as well...

Re: Time-based Gravity

Posted: Tue Feb 03, 2009 9:26 pm
by MarauderIIC
this->yvelocity -= gravity;
this->yposition += yvelocity;

?

"time" can literally be time elapsed between time(NULL) calls but the general rule is that if you can fake it well and fake it fast then don't spend the time doing it "real" and not-fast.

Re: Time-based Gravity

Posted: Tue Feb 03, 2009 10:32 pm
by Falco Girgis
I have a question for you and anybody else who bases their physics system on time. Why?

Why not just assume every frame is a unit of time? The calculations are easier (no numerical derivatives/integration for values), and everything is easier.

The acceleration due to gravity is -9.8j (j being the verticle component of the vector). You can calculate velocity from this by integrating. You can calculate position by integrating that again.

Okay, here's the calculus:

a(t) = -9.8 (constant acceleration)
v(t) = -9.8t + c (c is your constant of integration, being your initial velocity)
p(t) = -4.9t^2 + ct + c2 (ct being initial velocity times time, c2 being initial position).

Integrating acceleration gives us velocity, integrating velocity gives us position.

Re: Time-based Gravity

Posted: Tue Feb 03, 2009 10:38 pm
by Joeyotrevor
Well when I turn vsync off or I use a monitor with a different refresh rate and my app is running at 3500fps I don't want to guy to be moving around at the speed of light. :P

Re: Time-based Gravity

Posted: Tue Feb 03, 2009 10:40 pm
by Falco Girgis
That's not the approach you want. You need to put something in your main loop that makes the entire frame take longer rather than basing every single thing off of time.

Basically:

Code: Select all

for(;;) { //heartbeat

    GetInput()
    Render()
    DoShit()

   //DO NOTHING UNTIL A CERTAIN AMOUNT OF TIME PASSES.
}

Re: Time-based Gravity

Posted: Wed Feb 04, 2009 12:05 pm
by M_D_K
The whole point of time based movement is so it doesn't matter if you run at 30fps or 300fps you will move the same amount of distance in a second.

anyways

Code: Select all

//this is all you need for time based movement...
//timems = Delta time. This is the amount of time thats passed since the last frame to this one
	m_velocity.x += m_acceleration.x * timems;
	m_velocity.y += m_acceleration.y * timems;
	m_velocity.z += m_acceleration.z * timems;

	m_position.x += m_velocity.x * timems;
	m_position.y += m_velocity.y * timems;
	m_position.z += m_velocity.z * timems;

Re: Time-based Gravity

Posted: Wed Feb 04, 2009 12:25 pm
by Falco Girgis
edit: nevermind.

I misinterpreted. Yeah, you are basing it off of the delta and are only using it to determine movement. I see people who use functions of total time to describe their physics as if they grabbed some equation straight from a physics book and didn't even think about it.

By adding the changes every frame (as you are doing), you are eliminating the parameter t from the physics formulas. Since a frame is equivalent to 1 of whatever the hell unit of time you are wanting to use, still having a parameter t in your equations is pointless.

But yeah, your answer is what he was looking for.

Re: Time-based Gravity

Posted: Wed Feb 04, 2009 12:41 pm
by M_D_K
OH YEAH! I was helpful :)

Re: Time-based Gravity

Posted: Wed Feb 04, 2009 2:28 pm
by LeonBlade
M_D_K wrote:The whole point of time based movement is so it doesn't matter if you run at 30fps or 300fps you will move the same amount of distance in a second.

anyways

Code: Select all

//this is all you need for time based movement...
//timems = Delta time. This is the amount of time thats passed since the last frame to this one
	m_velocity.x += m_acceleration.x * timems;
	m_velocity.y += m_acceleration.y * timems;
	m_velocity.z += m_acceleration.z * timems;

	m_position.x += m_velocity.x * timems;
	m_position.y += m_velocity.y * timems;
	m_position.z += m_velocity.z * timems;
Listen to M_D_K... he knows what he is talking about LOL he helped me out with my physics... granted it's not perfect (didn't start from scratch) but I now understand how it works.

Re: Time-based Gravity

Posted: Thu Feb 05, 2009 8:17 pm
by Joeyotrevor
Thanks guys!

Re: Time-based Gravity

Posted: Fri Feb 06, 2009 1:00 am
by CC Ricers
For future reference, if you want to keep your actions independent of the rendering, I suggest you keep your functions for graphics rendering totally separated from your game actions. This will be useful for older computers that might suffer some slowdown in the graphics. Incidentally, this will lock the peak framerate of your program, but when slowdown occurs, game actions continue on their own, avoiding situations where everything, such as the gravity, is running in slo-mo.

Code: Select all

frameTime = 20; // in milliseconds
while(running) {

    currentTime = getMilliseconds();
    timeCount += (currentTime - lastTime);
    lastTime = currentTime;

    if(timeCount > frameTime) {
        display();
	// Continuously take events
        while(timeCount > frameTime) {
            handleActions();
            timeCount -= frameTime;
        }
    } else {
        // optional sleep function, to conserve CPU usage
    }
}

Re: Time-based Gravity

Posted: Tue Feb 10, 2009 11:24 am
by Arce
Honestly, I intentionally design my projects so that a slowdown IS universal; I don't like a rendering slowdown to cause death because the rest of the game is still running and you can't see what the fuck is going on. xD

Though there are definately time and instances where I'd use your independant draw methods, namely network and socket apps.

Re: Time-based Gravity

Posted: Fri Feb 13, 2009 4:22 am
by systat
Joeyotrevor wrote:Well when I turn vsync off or I use a monitor with a different refresh rate and my app is running at 3500fps I don't want to guy to be moving around at the speed of light. :P
Frame limiter, does it ring the bell?


Sorry for my bad english.

Re: Time-based Gravity

Posted: Sat Feb 14, 2009 1:59 pm
by RyanPridgeon
Commercial games control speed with time by using the time elapsed since the last time the player moved.

a shoddy way of explaining it would be;
change in position = movespeed x time

For instance, if it has been 5 ticks since last time, move the player 10 pixels, if it has been 10 ticks, move the player 20 pixels.

You can get the total ticks since the start of the program in SDL by using SDL_GetTicks()