What's wrong with this gravity function?
Hello all,
I tried implementing simple gravity in my demo. I have just two objects at the moment, and I experience that the second object feels forces twice as strong as the first object.
An example would be two balls that feel upward forces. They leave the ground together, but one object "jumps" twice as high as the other, yet they still land together. I ripped out everything that doesn't act on Y.
I apologise if the following code is somewhat messed up and ineffective, I wrote if for readability. Any corrections are appreciated.
static DWORD newtime = timeGetTime(), oldtime = timeGetTime();
float thistime;
std::vector::iterator unitit = allunits->units.begin();
int i = 0;
newtime = timeGetTime();
thistime = (float)(newtime - oldtime)/1000; //thistime is in seconds
if(thistime == 0) return 1; //High fps or first run, return without doing anything
while(i < allunits->num)
{
(*unitit).velocity.y -= (constants::m_gravity * thistime); //Apply gravity
(*unitit).origin.y += ((*unitit).velocity.y * thistime);
if((*unitit).origin.y < 0) (*unitit).origin.y = 0;
if((*unitit).origin.y == 0 && (*unitit).velocity.y != 0) //Bounce
{
(*unitit).velocity.y = fabsf((*unitit).velocity.y * 0.5); //Bounce off with half the original speed
}
if(keys[VK_UP] && ((*unitit).origin.y == 0)) (*unitit).velocity.y += 10.0;
i++;
unitit++;
}
[edited by - Uberapan on August 10, 2003 12:53:02 PM]
I can''t see anything obviously wrong here. If you have three objects, does the third experience normal, double or triple forces?
CoV
CoV
i think the first problem is your ''oldtime'', i think ur using it to determine how long since last update. but you never update oldtime, so you actually have the total time since -first- frame.
this would explain your problem if your [ (*unitit).origin.y ] is an int, it should be a float.
also . . .
if(thistime == 0) return 1; //High fps or first run, return without doing anything
float == 0
bad form
(*unitit).velocity.y -= (constants::m_gravity * thistime); //Apply gravity
m_gravity*thistime doesnt change, so you can take it out the loop
if((*unitit).origin.y < 0) (*unitit).origin.y = 0;
if((*unitit).origin.y == 0 && (*unitit).velocity.y != 0) //Bounce
these two lines can easily be put together
and where did .heading come from?? why not just adjust .velocity directly?
and you can use Code /code tags to make IF more readable
There are currently 652 cheeses in our database.
this would explain your problem if your [ (*unitit).origin.y ] is an int, it should be a float.
also . . .
if(thistime == 0) return 1; //High fps or first run, return without doing anything
float == 0
bad form
(*unitit).velocity.y -= (constants::m_gravity * thistime); //Apply gravity
m_gravity*thistime doesnt change, so you can take it out the loop
if((*unitit).origin.y < 0) (*unitit).origin.y = 0;
if((*unitit).origin.y == 0 && (*unitit).velocity.y != 0) //Bounce
these two lines can easily be put together
and where did .heading come from?? why not just adjust .velocity directly?
and you can use Code /code tags to make IF more readable
There are currently 652 cheeses in our database.
Fatray,
Thanks for your answers. The "heading" is just what I used instead of velocity. I changed the name for readability. I thought I had changed them all, but I must have missed that one.
To answer:
1. I do update oldtime. It wouldn''t work otherwise
This is a much larger function, and I ripped out the unnecessary parts. It''s set to oldtime = newtime at the end. That way I can get the elapsed time by subtracting oldtime from newtime the next time through.
2. Everything are floats.
3. You''re right about float == 0, I''ll change it...
Thanks! Too bad my problem still persists, though
Thanks for your answers. The "heading" is just what I used instead of velocity. I changed the name for readability. I thought I had changed them all, but I must have missed that one.
To answer:
1. I do update oldtime. It wouldn''t work otherwise
This is a much larger function, and I ripped out the unnecessary parts. It''s set to oldtime = newtime at the end. That way I can get the elapsed time by subtracting oldtime from newtime the next time through.
2. Everything are floats.
3. You''re right about float == 0, I''ll change it...
Thanks! Too bad my problem still persists, though
Maybe one is heavier than the other!
Actually your code has a very common mistake. The "correct" formula is this:
You have (effectively) implemented it like this:
Notice the difference?
Actually your code has a very common mistake. The "correct" formula is this:
di = di-1 + vi-1t + .5 * gt2vi = vi-1 + gt
You have (effectively) implemented it like this:
di = di-1 + vi-1t + gt2vi = vi-1 + gt
Notice the difference?
Well, I feel quite embarrased now. I found the problem after two full days of debugging. Actually, the problem was not in that function at all, but rather in the rendering loop. That's it, from now on I will make sure to print all variables to the screen while debugging... I still have problems with not naively trusting what the computer renders to screen.
JohnBolton, thanks for pointing that out. It's been too long since I took basic physics
[edited by - Uberapan on August 12, 2003 11:42:06 AM]
JohnBolton, thanks for pointing that out. It's been too long since I took basic physics
[edited by - Uberapan on August 12, 2003 11:42:06 AM]
glad you got it fixed Uberapan, good luck with your project.
There are currently 652 cheeses in our database.
There are currently 652 cheeses in our database.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement