Skip to main content
gamedev.net
🔒 Locked

gravity problem..

Started by Forrest2006 Jan 24, 2007 at 5:35 AM 7 replies 950+ views
Original Post
Forrest2006
Forrest2006
I want to create realistic gravity(using newton's 2nd law formula)..but there seems to be a problem with timer...

#include<allegro.h>
#include<winalleg.h>
BITMAP *buffer;
int main()
{
    int v=100;     //vertical speed     
    int y;         //the y variable
    
    allegro_init();
    install_keyboard();
    //set_color_depth(32);
    set_gfx_mode( GFX_AUTODETECT, 800, 600, 0, 0);
    acquire_screen();
    buffer = create_bitmap(800, 600);   
    for(int i=0;i<=800;i++)                         //ground plane basically
    putpixel(buffer,i,500,makecol(200,200,200));
    float time=GetTickCount()/1000;                 //time stuff
    float time1;
    while(!key[KEY_ESC])
    {
                        clear_to_color(buffer, makecol( 0, 0, 0));
                        
                        for(int i=0;i<=800;i++)
                        putpixel(buffer,i,500,makecol(20,20,20));
                        
                        time1=(GetTickCount()/1000)-time;
                        
                        y = 500 - (v*time1) + (5*(time1*time1)); //NEWTONS SECOND LAW y=ut-1/2gt^2
                        
                        putpixel(buffer,400,y,makecol(200,200,200));
                        
                        blit(buffer, screen, 0, 0, 0, 0, 800, 600); 
                        }
                        
                        release_screen();
                        return 0;
                        }
                        END_OF_MAIN();

capricorn
capricorn
Please explain your problem in more detail. 'A problem with timer' doesn't say much. What gets wrong?
WBW, capricorn
Forrest2006
Forrest2006
the problem is that the object/pixel is moving in discrete locations..not continuous.like it moves to y=500 for one moment than to like 300 to other..but it should be like a continuous graph.
I think the timer function i am using is not able to capture enough small time intervals to make it move smoothly.
waferthinninja
waferthinninja
Is the problem to do with integer division?

if getTickCount() returns an int, say 678 then when you divide by 1000 you get 0 using integer division, so you will only get an update every 100 ticks. Divide by 1000.0 and it should work (assuming I am not barking up the wrong tree!).

As an aside, I wouldnt use y=ut-1/2gt^2, but would instead keep track of the objects velocity as a vector, and apply a gravity vector to it each frame.



taby
taby
Quote:
Original post by Anonymous Poster
yeah what 'ninja said

except you should probably use an explicit cast to float, rather than rely on type coercion; better habit anyway


so do this:

time=(float)gettickcount()/1000.0f;

and similar for the timel line...

timel=((float)gettickcount()/1000.0f)-time

note the 'f' at the end of 1000.0 that designates it to be a floating point value, not an integer value


In C++ casting style: time = static_cast(tickcount())/1000.0f;
JohnBolton
JohnBolton
Don't cast the value returned by GetTickCount() to a float. GetTickCount() can return a 32-bit value, but float only has 24 bits of precision. The result is that there will be no movement (most of the time). Either use double (which has 56 bits of resolution) or do something like this:
    DWORD old_time;    ...    DWORD new_time = GetTickCount();    float dt = float( new_time - old_time ) * 0.001f;    old_time = new_time; 
Quote:
Original post by waferthinninja
As an aside, I wouldnt use y=ut-1/2gt^2, but would instead keep track of the objects velocity as a vector, and apply a gravity vector to it each frame.

1. Why replace the formula? It works for vectors too. Anything else would not be realistic.
1. Using vectors would be applicable in 3D, but this is simple 2D.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Forrest2006
Forrest2006
yes the integer div was the problem...and also using double makes it more smoother as John said.I think the formula is perfect as far as you dont want to use collisions.
waferthinninja
waferthinninja
There is no reason you cant use velocity vectors in 2D instead of 3D, theres nothing inherantly 3D about a vector. Stuff like detecting collision is why you might want to. You can then, for example, simply reverse the velocity on hitting a wall for example. Using your equation, you would need to do another calculation (v = u + at) to determine the velocity at any given moment.

You will get exactly the same motion applying the gravity each frame. Newtons equation is just the result of integrating that movement over time. Applying the gravity each frame is a lot quicker (addition rather than a bunch of multiplication). It wont make much difference for your simple example, but if you are tracking the motion of hundreds of things it would add up.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.