Lab 6: Breakout, Part III
Objectives
-
to practice using inheritance.
-
to see the use of overriding for accepting user events.
Part A. Overview
In this lab, we complete our Breakout program by adding a paddle that
the user manipulates. We'll accomplish this by slightly modifying
our Ball and Block classes from
Lab 2, then by
defining two subclasses - one to represent a paddle (which is a
subclass of the Block class, inheriting the rectangular properties
defined there), and one to represent the window (which exists primariy
to override the keyTyped() method called by DrawableFrame
each time a key is typed).
After we finish, we'll have the following inheritance hierarchy for our
program.
Perform the following steps.
- Run getcs to get the distributed
files for this lab.
Then copy your files from Labs 2 and 4
into the Lab 6 directory.
% getcs 160 6
% cp ~/CS160/Lab2/*.java ~/CS160/Lab4/*.java ~/CS160/Lab6
- Start Forte. Before doing anything else, close
all open files by repeatedly right-clicking in the Source Editor window
and choosing Close from the pop-up menu. Closing all Java files is
very important to avoid later confusion!
- Open the Java files from the Lab6
directory, and modify
their package lines to reflect that you are now working on
the Lab6 package.
Also, you will no longer want to import the
Lab2 package in Breakout.java.
Part B. Modifying previous classes
Modify the Ball, Block, and Breakout
classes as follows.
- Add a new constructor to Ball that takes another
Ball as a parameter and copies all the instance variables of that
ball into the instance variables of the new ball.
- Modify the step() method of Ball so that it does not bounce
off the bottom of the window. Also, modify this method to return a
boolean indicating whether the ball is still on the screen after
the ball is stepped.
- Add the following methods to the Block class.
- int getLeft()
-
Returns the x-coordinate of the block's left side.
- int getRight()
-
Returns the x-coordinate of the block's right side.
- void shiftRight(int dist)
-
Shifts the block dist pixels to the right.
- In main(), create a variable init_ball to hold the
ball as read in from the file. Then, after it is created, use your new
constructor method to create a new Ball.
Ball ball = new Ball(init_ball);
Thus, while ball moves, init_ball remains unchanged.
Once ball goes off the window, you can create a new ball
at the initial state specified in the file
by simply creating another copy of init_ball.
- If the step() method of Ball returns false, then you
should reinitialize the ball variable
(copying from init_ball using the new Ball constructor method).
This should make the ball reappear at its initial
location when the ball goes off the bottom of the window.
Also, you should decrease the score by 25 when this occurs.
Before going on, test the above to make sure the program works as it
ought. Of course there is still no paddle, but when the ball reaches the
bottom of the window, it should reappear at its initial location (and
the score should go down).
Part C. The Paddle class
Define a new class called Paddle, a subclass of the
Block class, with the following constructor.
- Paddle(int in_left, int in_top, int in_width, int in_height)
-
Creates a paddle in_width pixels wide and in_height pixels
tall, whose top left corner is initially at
(in_left,in_top).
Instance variables for the paddle's position and size are inherited
from the Block class. These instance variables are declared
private in Block, but you won't need to access them directly.
Instead, you can use Block's instance methods.
You will want the Paddle class to define a private instance
variable to track the paddle's current velocity. The paddle's
initial velocity will be 0.
The Paddle class should add the following two methods.
- void addToVelocity(int delta)
-
Modifies the paddle's velocity by delta.
- void step(DrawableFrame frame)
-
Shifts the paddle according to its current velocity, keeping within
frame.
Shifting the paddle is similar to shifting the ball, but it's much
simpler since the paddle only moves horizontally. When the paddle hits
the edge of the frame, it should move no further. I recommend
resetting the paddle's velocity to 0 when this occurs.
Part D. The BreakoutFrame class
Extend the DrawableFrame class with a class named
BreakoutFrame.
This class will have a new instance variable to represent the paddle
within the frame. (The constructor method for the frame will initialize
the paddle to its initial location. I recommend a 40x15 paddle,
initially located at (10,170).)
The BreakoutFrame class should define the following two methods.
- Paddle getPaddle()
-
Returns the paddle.
- void keyPressed(char c)
-
Changes the paddle's velocity based on c: The comma key
should decrease the velocity by 1 and the period key should
increase the velocity by 1.
Part E. Finishing Breakout
The following modifications will allow you to complete the game.
- Modify main() to use the BreakoutFrame class instead
of DrawableFrame.
- When you're stepping the ball, you should both
step the paddle and bounce the ball off the paddle.
(To access the paddle, you can call getPaddle()
on the BreakoutFrame object.)
- In the process of drawing the screen, main() should tell
the paddle to draw itself.
When you run the program, the paddle should be drawn on the screen,
the user should be able to control the paddle via the keyboard,
and the ball should bounce off the paddle.
Your game is complete.