Game physics are wrong(ball bouncing)

Hi guys,

so apparently my math calculations must be way off,I am trying to create the physics for a ball bouncing each time it's dropped,the Y access in SDL starts at the top and is 0 and goes downwards towards the end of the window given your window height,I know roughly each time a ball is bounced it's height will be approx half that of it's previous height,so lets say when my ball is dropped from the height of 23 well half of that is 11.5 but obviously that won't work so I thought of the opposite,multiplication

so ballDroppedY* = 2 will be 23 by 2 which equals 46 so half of 46 is 23,but this may hold true it doesn't hold true for my game as this is still not half the distance from the highest point it was dropped and the minimum point(the platform)

could anyone point me in the right direction as to where and how my calculations are wrong?

thanks


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

bool collision(){

  if(ballDstRect->y + ballDstRect->h >= platformDstRect->y && platformOne){

    //cout << "colission platform one" << endl;
    ballDown = false;
    ballDstRect->y = platformDstRect->y - ballDstRect->h; // line that fixed the bug

    return true;
  }
  if(ballDstRect->y + ballDstRect->h >= platformTwoDstRect->y && platformTwo){

    //cout << "colide platform 2" << endl;
     ballDown = false;
     ballDstRect->y = platformTwoDstRect->y - ballDstRect->h; // also fixed the bug

    return true;
  }
  //cout << "return collision false" << endl;
  return false;

}

void move();
void renderGame();

void getBallY(){

    ballDroppedY = ballDstRect->y;

}

bool bounce(){

    cout << "before (double) 0.5 * ballDroppedY ->" << ballDroppedY << endl;

    ballDroppedY *= 2;

    cout << " firstBALL -> " << ballDstRect->y << endl;
    cout << " first ball Dropped Y (firstBall *= 2 -> " << ballDroppedY << endl;

    if(platformOne){

    while(ballDstRect->y >= ballDroppedY){

        cout << "RISING :: BALL -> " << ballDstRect->y << endl;
        cout << "RISING :: ball Dropped Y " << ballDroppedY << endl;
        cout << "RISING :: playform y " << platformDstRect->y << endl;
        ballDstRect->y -= 2;
        SDL_Delay(1);
        renderGame();
    }
    while(ballDstRect->y + ballDstRect->h <= platformDstRect->y){

        cout << "IN HERE" << endl;
        cout << " FALLING :: BALL -> " << ballDstRect->y << endl;
        cout << "FALLING :: ball Dropped Y " << ballDroppedY << endl;
        cout << " FALLING :: playform y " << platformDstRect->y << endl;
        ballDstRect->y += 2;
        SDL_Delay(1);
        renderGame();
    }
    if(ballDroppedY >= platformDstRect->y && platformOne){

        cout << "BOUNCE TRUE" << endl;
        return true;
    }
    }
     cout << "BOUNCE FALSE" << endl;
     return false;
}


// drop ball allow no user input
void ballDrop(){

  while(true){

     cout << "BALL DROP" << endl;
     move();
     renderGame();
     SDL_Delay(2);

     if(collision()){

        while(ballDropped){

            if(bounce()){

                break;
            }

        }

        break;
        }
     }

  ballDropped = true;
  return;

}

int SDL_main(int argc,char* argv[])
{

    initGame();

    bool quit = false;


    while(!quit){

        SDL_PollEvent(&event);

        if(!ballDropped){

            ballDrop();
        }

        if(event.type == SDL_QUIT){
            //cout << "quit" << endl;
            quit = true;
        }
        if(event.type == SDL_KEYDOWN){

            switch(event.key.keysym.sym){

        case SDLK_RIGHT:
            ballLeft = false;
            ballRight = true;
            rightStop = true;
            break;
        case SDLK_LEFT:
            ballRight = false;
            ballLeft = true;
            leftStop = true;
            break;
        case SDLK_UP:
            jump();
            renderGame();
            //cout << "UP" << endl;
            jumping = true;
            jumpDown = true;
            break;
            }
            moveBall(quit);

        }
        if(event.type == SDL_KEYUP && jumpDown){

            switch(event.key.keysym.sym){

          case SDLK_UP:
            getBallY();

            ballDrop();
            jumpDown = false;
            jumping = false;
            ballRight = false;
            ballLeft = false;
            //cout << "down" << endl;
            break;
            }
            moveBall(quit);
        }
        if(event.type == SDL_KEYUP && rightStop){

            switch(event.key.keysym.sym){

          case SDLK_RIGHT:
            ballRight = false;
            break;
            }
            moveBall(quit);
            rightStop = false;
        }
        if(event.type == SDL_KEYUP && leftStop){

            switch(event.key.keysym.sym){

          case SDLK_LEFT:
            ballLeft = false;
            break;
            }
            moveBall(quit);
            leftStop = false;
        }

        SDL_Delay(1);
        renderGame();
    }
}
to really sim the physics you need to iterate 'time' in seconds (does not have to match real seconds) and calculate the position. When it hits the ground it gets an impulse back up that slowly drains off by the negative acceleration of gravity until it falls again, and so on.

so at time zero, distance from where you were is zero, initial velocity is zero, and gravity is g. so its position is 1/2g*0 + 0= 0 … it hasn't moved.
time 1, position is 1/2g*1*1 + 0.
time 2, position is 1/2g*2*2+0..
until that is equal to the distance traveled to impact, eg 23.
if g is 10 pixels /sec/sec, then (this makes 1 meter 1 pixel roughly)
it will impact in about 2.1 seconds. Likely you will adjust this so a meter is many pixels so it is more interesting, but you can do that part yourself.
when it reaches 23 distance, it impacts (don't even need to check collision, its known) and you do the same math except with initial velocity. Say the initial velocity is 15.
time = 0 (starting over every time it impacts) as above its zero, unchanged.
time 1, d = 1/2g*1*1+15*1
and so on. after a bit it will stop going up, slow, go back down, impact, and repeat this. the first iteration is the only one that is odd, because it starts in the air instead of on a bounce. all the others are the same.
at some point the initial velocity is very low and you should stop; your sim might go on for a long, long time trying to iterate fractions of pixels (like trying to walk half way to something every loop but never reaching it forever).


> I know roughly each time a ball is bounced it's height will be approx half
> that of it's previous height, so lets say when my ball is dropped from the
> height of 23 well half of that is 11.5 but obviously that won't work so I
> thought of the opposite,multiplication (¿?)

> so ballDroppedY* = 2 will be 23 by 2 which equals 46 so half of 46 is 23,but
> this may hold true it doesn't hold true for my game

¿what?
you want to divide by two, so you instead multiply
I don't understand you


the ball doesn't reach its initial height because some of its energy was dissipated as heat in the collision (no air resistance, don't remember the equations)
so you dropped the ball from height `h', it travelled a time `t' and reached a velocity of `v_f' upon impact
In constant acceleration h = 1/2 v_f t (a right triangle of area `h' with `t' for base and `v_f' for height, the acceleration is the tangent of the angle)
you want it to reach half that height, so you need a similar triangle (same acceleration) with half the area
1/4 v_f t = 1/2 \alpha v_f \alpha t -> \alpha = 1/sqrt(2) ~ 0.707

so, after the collision, your velocity will be 0.707v, and it 0.707t you'll reach the peak at half the height from which you started.
Topic archived. No new replies allowed.