Skip to main content
GameDev.net gamedev.net
🔒 Locked

Simple Bouncing Problem

Started by SMurf7 Nov 4, 2006 at 8:58 AM 3 replies 700+ views
Original Post
SMurf7
SMurf7
Hello, I'm trying to simulate an object vertically falling with gravity and bouncing against another object, with no horizontal forces involved. Currently I have the following being executed every cycle (60 Hz):-

if (tt->dVelocity || !DetectRect(me->parent, me, me->x, me->y + 1, me->w, me->h))
{
    tt->dVelocity += GRAVITY * 0.02;
    if (tt->dVelocity > 0)
        me->y += (tt->dVelocity - (int)tt->dVelocity >= 0.5) ? (int)tt->dVelocity + 1 : (int)tt->dVelocity;
    else
        me->y += ((int)tt->dVelocity - tt->dVelocity >= 0.5) ? (int)tt->dVelocity - 1 : (int)tt->dVelocity;

}

The code basically checks to see if double dVelocity is nonzero or there is nothing immediately beneath the object. Then it adds the acceleration due to gravity to the velocity (multiplied by 1/60th of a second) and rounds the result in either sign to increment the y position. Thn we have the code that is executed when the object hits something:-

char szTemp[64];

sprintf(szTemp, "%lf -> ", tt->dVelocity);
OutputDebugString(szTemp);
tt->dVelocity *= 0.4;
tt->dVelocity = -tt->dVelocity;
sprintf(szTemp, "%lf\n", tt->dVelocity);
OutputDebugString(szTemp);

The velocity is reduced to 2/5 of its original value and then inverted to signify velocity in the opposite direction (up). Unfortunately it doesn't seem to work as planned. The object continues to bounce to a particular height. The results from the OutputDebugString calls are:- 7.840000 -> -3.136000 3.332000 -> -1.332800 2.979200 -> -1.191680 2.924320 -> -1.169728 2.750272 -> -1.100109 3.015891 -> -1.206356 2.713644 -> -1.085457 3.030543 -> -1.212217 2.707783 -> -1.083113 2.640887 -> -1.056355 2.863645 -> -1.145458 2.970542 -> -1.188217 2.731783 -> -1.092713 The velocity seems to oscillate over time and I don't know why. :(
JohnBolton
JohnBolton
It is likely that this is the problem:
    me->y += (tt->dVelocity - (int)tt->dVelocity >= 0.5) ? (int)tt->dVelocity + 1 : (int)tt->dVelocity; 
Normally it would be y += v * t. I'm not quite sure what you are doing, but you aren't incorporating time into the computation. Well, perhaps you are implicitly and that's why it seems to work to some degree. I suspect it is also related to the use of integer values.

Change y to floating point and use y += v * t and see if that makes a difference.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
StealthNinja
StealthNinja
No idea if this is the problem or not, but I've always added gravity all of the time, and just let the collision response reset velocity to 0 if something happens to be beneath you.
SMurf7
SMurf7
JohnBolton: Yeah, I've seen y += v * t around before, it just seems to make the object fall really slowly (t = 0.02 or 1/60) and then when it hits something it appears about 60 pixels above it and doesn't move. [headshake]

Unfortunately I can't draw on fractions of pixels so I don't see what benefit making x/y floating point would give.

EDIT: I owe you an apology. After storing a separate double of y for use in these calculations and fixing some collision code it now works! Using y += v * t is still quite slow though.


StealthNinja: Gravity is added every frame, even if there's a collision. I need the velocity to be reduced and inverted rather than set to 0 to simulate a bounce.

[Edited by - SMurf7 on November 4, 2006 6:29:38 PM]
JohnBolton
JohnBolton
Quote:
Original post by SMurf7
Yeah, I've seen y += v * t around before, it just seems to make the object fall really slowly (t = 0.02 or 1/60)...

The slowness is probably due to your units. You can either decide how big a pixel is and then use real world units, or just tweak the gravity value until the falling looks good, if you want to stick with pixel units.

Now, when I wrote "y += v * t", I was simplifying the math so that it would be easier to implement, and it is close but it is not really the correct answer. The real equations are these:
    v = v<sub>0</sub> + gt    y = y<sub>0</sub> + v<sub>0</sub>t + ½gt<sup>2</sup> 
t = time since start (start can be the time of the last frame or the last collision, the result should be the same)
g = acceleration due to gravity
v0 = starting velocity
y0 = the starting height
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!

Topic Locked

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

Sign in to reply to this topic.