Your balls are getting stuck because they aren't escaping the area where you are detecting collisions with the wall. I was able to fix this by checking if the ball's speed has the correct sign (positive or negative) for the particular collision you are testing for. I also replaced the 30s with the ball's radius, which is what was intended, but see the note below.
- void boundingArea(){
- // EDGES OF THE SCREEN
- if(ballY > height-ballRadius && speedY > 0) {
- speedY *= -drag;
- }
- if(ballY < ballRadius && speedY < 0) {
- speedY *= -drag;
- }
- if(ballX > width-ballRadius && speedX > 0) {
- speedX *= -drag;
- }
- if(ballX < ballRadius && speedX < 0) {
- speedX *= -drag;
- }
- }
A few other suggested fixes:
* Add this in your setup:
And then if the balls look too big, make your radii smaller. You are passing radii to the ellipse function, but by default, it uses diameters, unless you perform the above line. For some of the other changes I'm suggesting, it's important that radius means radius.
* Just for fun, I think the W and S keys are kind of interesting if you change the ball's gravity, rather than the ball's speed.
- if (key == 'w' || key == 'W')
- gravity *= 1 / 1.1;
- if (key == 's' || key == 'S')
- gravity *= 1.1;
Finally, ball to ball collision detection. This can slow down your code a bit, but the basic idea is to stick a loop like thisfollows into your main draw() routine, that compares every ball to every other ball.
- for (int i = 0; i<numBalls-1; i++) {
- Ball b1 = ball[i];
- for (int j = i+1; j<numBalls; j++) {
- Ball b2 = ball[j];
- float dx = b2.ballX - b1.ballX;
- float dy = b2.ballY - b1.ballY;
- float d = sqrt(sq(dx)+sq(dy)); // distance between balls
- if (d < b1.ballRadius+b2.ballRadius) {
- // The two balls are colliding.
- }
- }
- }
-
Here's a version where I've added code that also causes the balls to bounce off of each other. If you use this, you should reduce the number of balls (to maybe 10) and separate them from the other at the outset. This will act funny if the balls are coincident, as they are now. Also give them some randomized initial speeds... This *will* slow down your code a lot with a lot of balls.
- for (int i = 0; i<numBalls-1; i++) {
- Ball b1 = ball[i];
- for (int j = i+1; j<numBalls; j++) {
- Ball b2 = ball[j];
- float dx = b2.ballX - b1.ballX;
- float dy = b2.ballY - b1.ballY;
- float d = sqrt(sq(dx)+sq(dy)); // distance between balls
- if (d < b1.ballRadius+b2.ballRadius) {
- // The two balls are colliding.
- float mag1 = sqrt(sq(b1.speedX)+sq(b1.speedY));
- float mag2 = sqrt(sq(b2.speedX)+sq(b2.speedY));
- b2.speedX = (mag1*dx/d)*b1.drag;
- b2.speedY = (mag1*dy/d)*b1.drag;
- b1.speedX = -(mag2*dx/d)*b2.drag;
- b1.speedY = -(mag2*dy/d)*b2.drag;
-
- }
- }
- }
-