I've implemented gravity in what probably a non-standard way, but the calculus involved in actual rigid-body physics is too much math for me at my current ability.
CBall is my Ball class containing x and y positions, and x and y velocities. I have a vector of CBall pointers. I process them in this function named 'Gravity' detailed below.
I was curious to any comment at all on how to improve my design, or a new direction. This function runs once per frame, and processes every CBall pointed to in vpCBall (vector of pointers to CBall).
There are some kludges, like artificially adjusting the y position after a velocity inversion (the part where I multiply y_vel by a negative INERTIA) so that the y_vel isn't flipped again on the following loop/frame.Code:void Gravity(vector<CBall*> &vpCBall, int Gravity_Setting, sf::String &Text) { // Is gravity on? if (Gravity_Setting == WEIGHTLESS) return; // Iterate through the CBall list // Reset Active Balls counter each loop int ActiveBalls = 0; for (vector<CBall*>::iterator iter = vpCBall.begin(); iter != vpCBall.end(); ++iter) { if((*iter)->AtRest) continue; ++ActiveBalls; // Spreed: Copy the Class members to local variables float x_pos = (*iter)->x_pos; float x_vel = (*iter)->x_vel; float y_pos = (*iter)->y_pos; float y_vel = (*iter)->y_vel; y_vel += GRAVITY; //0.82 y_pos += y_vel; x_vel *= DRAG; // 0.995 x_pos += x_vel; // If Collided with Floor... if (y_pos > SCREEN_BOTTOM) { // Reverse momentum - albeit weaker (80-95% strength) y_vel *= -INERTIA; // 0.95 // Is Kinetic energy exhausted? // Note: Cutoff must be less than GRAVITY // Reason: This section takes care of the problem of the "vibrating" balls. // No point to vibrating balls, so after a CUTOFF in movement in // the x and y axis, simply zero out both and mark it AtRest=true assert(CUTOFF < GRAVITY); if (fabs(y_vel) < CUTOFF && fabs(x_vel) < CUTOFF) { //cout << "Resting Ball..." << endl; x_vel = 0; y_vel = 0; (*iter)->AtRest = true; } // Set Ball to just above floorline // Reason: This garuntees the ball will not be caught next time // through the loop and re-considered for -another- immediate // velocity inversion y_pos = SCREEN_BOTTOM - 0.001; } // Check Screen Bounds // Reason: If the balls roll off the screen to 105% of the screen // width, simply stop considering them for physics calculations. if (x_pos > (SCREEN_RIGHT * 1.05)) { x_vel = 0; y_vel = 0; (*iter)->AtRest = true; } // Put the locals back into the Class (*iter)->x_pos = x_pos; (*iter)->x_vel = x_vel; (*iter)->y_pos = y_pos; (*iter)->y_vel = y_vel; } // String stream used for screen message stringstream ss(""); ss << "Active Balls: " << ActiveBalls << " / " << vpCBall.size(); Text.SetText(ss.str()); }



LinkBack URL
About LinkBacks


