The complete specification of assignment #3 can be found as part of the stream at iTunes.
Create a ball and get it to bounce off the walls
At one level, creating the ball is easy, given that it’s just a filled GOval. The interesting part lies in getting it to move and bounce appropriately. You are now past the “setup” phase and into the “play” phase of the game. To start, create a ball and put it in the center of the window. As you do so, keep in mind that the coordinates of the GOval do not specify the location of the center of the ball but rather its upper left corner. The mathematics is not any more difficult, but may be a bit less intuitive.
The program needs to keep track of the velocity of the ball, which consists of two separate components, which you will presumably declare as instance variables like this:private double vx, vy;
The velocity components represent the change in position that occurs on each time step. Initially, the ball should be heading downward, and you might try a starting velocity of +3.0 for vy (remember that y values in Java increase as you move down the screen). The game would be boring if every ball took the same course, so you should choose the vx component randomly.
In line with our discussion of generating random numbers last week, you should simply do the following:
- Declare an instance variable rgen, which will serve as a random-number generator:
private RandomGenerator rgen = RandomGenerator.getInstance();Remember that instance variables are declared outside of any method but inside the class.
- Initialize the vx variable as follows:
vx = rgen.nextDouble(1.0, 3.0); if (rgen.nextBoolean(0.5)) vx = -vx;This code sets vx to be a random double in the range 1.0 to 3.0 and then makes it negative half the time. This strategy works much better for Breakout than calling
nextDouble(-3.0, +3.0)which might generate a ball going more or less straight down. That would make life far too easy for the player.
Once you’ve done that, your next challenge is to get the ball to bounce around the world, ignoring entirely the paddle and the bricks. To do so, you need to check to see if the coordinates of the ball have gone beyond the boundary, taking into account that the ball has a nonzero size. Thus, to see if the ball has bounced off the right wall, you need to see whether the coordinate of the right edge of the ball has become greater than the width of the window; the other three directions are treated similarly. For now, have the ball bounce off the bottom wall so that you can watch it make its path around the world. You can change that test later so that hitting the bottom wall signifies the end of a turn.
Computing what happens after a bounce is extremely simple. If a ball bounces off the top or bottom wall, all you need to do is reverse the sign of vy. Symmetrically, bounces off the side walls simply reverse the sign of vx.
Start by initializing the ball, set its position and velocity:
private void setupBall() { double d = 2 * BALL_RADIUS; ball = new GOval(d, d); ball.setFilled(true); ball.setLocation(WIDTH / 2 - BALL_RADIUS, HEIGHT / 2 - BALL_RADIUS); add(ball); vy = VY_START; vx = rgen.nextDouble(1.0, 3.0); if (rgen.nextBoolean(0.5)) vx = -vx; }
To adjust the position of the ball move it by the current velocity:
private void moveBall() { ball.move(vx, vy); }
When the ball hits the top or bottom (for now) change its vertical velocity, if it hits a wall change its horizontal velocity:
private void checkForCollision() { double x = ball.getX(); double y = ball.getY(); double d = 2 * BALL_RADIUS; if ((y > HEIGHT - d) || (y < 0)) { vy = -vy; } if ((x > WIDTH - d) || (x < 0)) { vx = -vx; } }
Finally combine everything in an infinite loop:
public void run() { setupBall(); while (true) { moveBall(); checkForCollision(); pause(DELAY); } }
The code for this assignment is available on github.