Monday, September 13, 2010

Animated Bouncing Ball- The Bill Version

After I wrote up my Animated Bouncing Ball solution, my friend Bill left a comment. His suggestion had to do with how I tracked the location of my ball so I'd know when it had hit a wall and should reverse directions. My solution had been to declare the variables x and y, set them to the initial x and y coordinates of my ball, and change their value after each move the ball made to make them match the new coordinates. As Bill said, this is quite poor because you're tracking x and y in two places, leaving it inefficient and susceptible to bugs.

The truth is, I had wanted to use a built-in getX() kind of method, but I didn't think such a method existed, since it wasn't listed in the textbook. Then I talked to Andrew, a friend from work, and realized that not only were there hundreds of other methods for GOval than were in the book, but that Java has dozens of ways to conceptualize an oval, only one of which is the GOval class. It's like I've been walking around with blinders on and suddenly the blinders have come off and I realize there's much more than I even knew to look for. As my friend Jane says, half of programming is just knowing what to Google.

So, I looked up to see whether I can use getX() with the GOval class to make my program more efficient, and lo and behold, I can! New and improved code below.


/*
* File: BounceBall.java
* Name: 
* Section Leader:
* -----------------

*/

import acm.graphics.*;
import acm.program.*;
import java.awt.*;

public class BounceBall extends GraphicsProgram {
    public void run() {
        
//Create ball in initial centered position
     int centeredx = (getWidth()-DIAMETER)/2;
     int centeredy = (getHeight()-DIAMETER)/2;
        
     GOval ball = new GOval (centeredx, centeredy, DIAMETER, DIAMETER); 
        ball.setFilled(true);
        add(ball);

        int dx = 1; //Setting the size of the ball's steps
        int dy = 1;
        
        while(true) { //Getting the ball to move
            ball.move(dx, dy);
            pause(PAUSE_TIME);

//  Declare x and y variables to locate the ball
          
            double x = ball.getX(); 
            double y = ball.getY();
            
//"If" statements to test whether the ball is at a wall, and if so, reassign dx or dy to switch direction.
            
            if (x >= getWidth()-DIAMETER) { //If it hits the right-hand wall`
             dx=-dx;     
            }
            if (y >= getHeight()-DIAMETER) { //If it hits the bottom
             dy=-dy;
            }
            if (x == 0) { //If it hits the left-hand wall
             dx=-dx;
            }
            if (y == 0) {//If it hits the top
             dy=-dy;
            }
        }
        }
        
//Private Constants
        
        private static final int DIAMETER = 40;
        private static final int PAUSE_TIME = 20;     
      
    }