Archived

This topic is now archived and is closed to further replies.

Uberapan

What's wrong with this gravity function?

Recommended Posts

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]

Share this post


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

Share this post


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

Share this post


Link to post
Share on other sites
Maybe one is heavier than the other!

Actually your code has a very common mistake. The "correct" formula is this:
di = di-1 + vi-1t + .5 * gt2
vi = vi-1 + gt


You have (effectively) implemented it like this:
di = di-1 + vi-1t + gt2
vi = vi-1 + gt


Notice the difference?

Share this post


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

Share this post


Link to post
Share on other sites