Read carefully and follow exactly Java:
You are to write a Breakout game, using Java applets for animation. The requirements for this
program are designed so that you will also use an ArrayList, Generics, an abstract class,
polymorphism, and file I/O. Please read the following instructions very carefully, as they attempt
to explain how the various parts of the animation work; then you can update the applet, using
your knowledge of ArrayLists, Generics, abstract classes, and polymorphism.
Existing classes: There are a number of existing classes that are already written and ready for
use. They are contained in the file Breakout.java (they are not defined as public so they don’t
have to be in a file that matches their name). Please look them over carefully to see what
functionality is available. The classes (implemented inside Breakout.java) are:
Ball: this is defined as a subclass of Rectangle (even though that is geometrically invalid!). The
reason for this is so Ball can inherit data for its x coordinate, y coordinate, width, and height. It
also adds some data of its own (see the code) and methods (among others) to:
bounceLeftRight() (which changes the angle at which it moves after bouncing off a left or right
side),
bounceTopBottom() (which changes the angle at which it moves after bouncing off a top or
bottom)
move() (change its coordinates),
freeze()/unfreeze() itself,
It also inherits important methods from the Rectangle class
translate – changes its x and y coordinates respectively by the 2 numbers that are passed in
intersects(Rectangle other) – returns true if it intersects another Rectangle
intersection(Rectangle other) – returns the Rectangle that is the intersection
Paddle: this is also defined as a subclass of Rectangle so it inherits the same data/methods that
are described above for the Ball class. The fact that Ball and Rectangle are both Rectangles
means that code can ask a Ball if it intersects a Paddle, so it can easily tell when to make things
happen.
Wall: this is not in its own file, but rather in the Breakout.java file. Wall is also a subclass of
Rectangle to it is easy to determine if the ball has collided a wall.
The Breakout class (which is an Applet): if you look at the code for the Breakout class, you will
notice it has a number of things:
It is a subclass of Applet, so it inherits data and methods as well as the ability to function as an
Applet. For example, if you want to know the height of the applet you can ask it through the
this.getHeight(); method.
It implements the KeyListener interface, which gives it the ability to “listen” for keystrokes
from the keyboard. If you were to look up the KeyListener interface in the documentation, you
would find that anything that implements it must have the KeyPressed, KeyReleased, and
KeyTyped methods. These are all there; KeyPressed and KeyReleased set/unset Boolean flags
which remember that the left or right arrow keys are or are not being pressed.
It has a method called in.
Read carefully and follow exactly Java You are to write a Breakou.pdf
1. Read carefully and follow exactly Java:
You are to write a Breakout game, using Java applets for animation. The requirements for this
program are designed so that you will also use an ArrayList, Generics, an abstract class,
polymorphism, and file I/O. Please read the following instructions very carefully, as they attempt
to explain how the various parts of the animation work; then you can update the applet, using
your knowledge of ArrayLists, Generics, abstract classes, and polymorphism.
Existing classes: There are a number of existing classes that are already written and ready for
use. They are contained in the file Breakout.java (they are not defined as public so they don’t
have to be in a file that matches their name). Please look them over carefully to see what
functionality is available. The classes (implemented inside Breakout.java) are:
Ball: this is defined as a subclass of Rectangle (even though that is geometrically invalid!). The
reason for this is so Ball can inherit data for its x coordinate, y coordinate, width, and height. It
also adds some data of its own (see the code) and methods (among others) to:
bounceLeftRight() (which changes the angle at which it moves after bouncing off a left or right
side),
bounceTopBottom() (which changes the angle at which it moves after bouncing off a top or
bottom)
move() (change its coordinates),
freeze()/unfreeze() itself,
It also inherits important methods from the Rectangle class
translate – changes its x and y coordinates respectively by the 2 numbers that are passed in
intersects(Rectangle other) – returns true if it intersects another Rectangle
intersection(Rectangle other) – returns the Rectangle that is the intersection
Paddle: this is also defined as a subclass of Rectangle so it inherits the same data/methods that
are described above for the Ball class. The fact that Ball and Rectangle are both Rectangles
means that code can ask a Ball if it intersects a Paddle, so it can easily tell when to make things
happen.
Wall: this is not in its own file, but rather in the Breakout.java file. Wall is also a subclass of
Rectangle to it is easy to determine if the ball has collided a wall.
The Breakout class (which is an Applet): if you look at the code for the Breakout class, you will
notice it has a number of things:
It is a subclass of Applet, so it inherits data and methods as well as the ability to function as an
Applet. For example, if you want to know the height of the applet you can ask it through the
this.getHeight(); method.
It implements the KeyListener interface, which gives it the ability to “listen” for keystrokes
2. from the keyboard. If you were to look up the KeyListener interface in the documentation, you
would find that anything that implements it must have the KeyPressed, KeyReleased, and
KeyTyped methods. These are all there; KeyPressed and KeyReleased set/unset Boolean flags
which remember that the left or right arrow keys are or are not being pressed.
It has a method called init. For an Applet, the init method is called once when the Applet is
created and it is used to initialize things. In this sense, it works like a constructor. In the init
method, instances of 3 other classes are added to the Applet:
A KeyListener is added, but since it is a KeyListener itself, it defines itself to the the
KeyListener
A timer is also created, which is “set” to go off periodically and will set off an ActionListener
method. There is another class defined in the Breakout.java file called BounceActionListener,
which implements ActionListener. Its required method (actionPerformed) will simply tell the
Applet to repaint itself, thus providing the timing for the animation.
A MouseListener is added that will listen for mouse clicks. To be different, I defined a new class
(in the same Breakout.java file) called BounceMouseListener. If you find it and look at it, you
will see that it implements the MouseListener interface, which requires 5 methods and allows it
to listen for mouse events. All the methods are there but the only one that is actually used is
mouseClicked, which listens for when a button is clicked.
It has a method called update, which is actually called by paint and redraws the whole Applet. It
receives a Graphics object from whatever browser is calling and controlling the Applet; the
Graphics object is like a “pen” in that it has the ability to draw specific things and also change its
color to whatever is passed in. The update methods has code to use “double buffering” in which
an image is create (with its own Graphics object), everything is written to the image, and then the
whole image is written to the Applet. This eliminates flickering. In the update method, various
components are told to move and to draw themselves (passing a Graphics object). This is also
where we check if the ball intersects other things. See the Java documentation for the methods a
Graphics object can use to draw things.
What you need to code:
Create an abstract class called DrawableBrick, which should be a subclass of Rectangle (so it
also inherits the same data and methods defined above in the description of Ball; these will be
important). Also make it have an additional data item to store points (this will be used by its
subclasses). There should be a getPoints() method which returns the points. Finally, make it have
an abstract method called draw(Graphics g), which will have to be implemented by any class
which is a subclass of DrawableBrick.
The relationship between the classes that implement your bricks is shown below. See Create 4
subclasses of DrawableBrick. The details are listed below.
3. has data: has methods:
x, y, width, height (ints) boolean intersects(Rectangle r)
Rectangle intersection(Rectangle r)
has data: has method: color (a Color) getPoints()
points (an int)
has abstract method:
draw(Graphics g);
( all implement their own method: draw(Graphics g) )
The RedBrick class is given as an example. Change it so it is a subclass of DrawableBrick and
has no data (all will be inherited). Its constructor should only accept ints for x, y, width, and
height (not points). Its constructor should also “hard-code” the number of points that it is worth.
Its draw method draws it using the Graphics object that it receives. You should take out the
diagnonal line that is in the example one.
The XBrick class should be set up like the RedBrick class, except that when it draws itself, it
draws a white rectangle with diagonal lines in addition to the outline around the edge. You can
“hard-code” a different amount of points for it.
The StripeBrick class should be set up like the RedBrick class, except that when it draws itself,
it draws a white rectangle with some horizontal “stripes” in addition to the outline around the
edge. You can “hard-code” a different amount of points for it.
The OvalBrick should be set up like the RedBrick class, except that when it draws itself, it
draws 2 ovals inside itself. These ovals can be any color you want. Check the documentation for
the Graphics class to tell a Graphics object how to draw a filled oval. You can “hard-code” a
different amount of points for it.
See the image below for what the different bricks look like.
In Breakout’s data, declare an ArrayList that will hold DrawableBricks.
In Breakout’s init() method, actually create the ArrayList that will hold DrawableBricks. Then
open a file called bricklist.txt (OK to hardcode the name, but make sure it is correct). The file
might look something like what is shown below (FOR EXAMPLE – this is the file that would
produce the game shown above.).
2
3
OvalBrick
XBrick
OvalBrick
XBrick
RedBrick
4. StripeBrick
This file is telling you to have 2 rows, each with 3 columns. After the numbers should be 2x3 =
6 lines, each with a type of DrawableBrick. Create each type of DrawableBrick, carefully
calculating the x, y, width, and height. Put it into the ArrayList that you created.
(You should experiment with changing bricklist.txt to have different number and types of
bricks…)
The rows should exactly fit across the usable space (not including the walls). Their height can be
any number you want. The gap at the top should be at least 3 times the ball diameter.
NOTE: You can read the name of the brick type with a .next(). If you decide to use .nextLine(),
remember what happens when you try to read an int ( using nextInt() )and then a line ( using
nextLine() ).
In Breakout’s update() method, you will have to provide the actual logic that will make it all
work. After the ball is told to move, there is existing code which checks to see if the ball hit a
wall or a paddle. You have to add code to check if the ball it any one of the various bricks that
are in your ArrayList – if so, tell the ball to bounce (correctly – either a “side bounce” or a
“top/bottom bounce”), update the number of points (see the comment in the Breakout.java
update() code), and tell the ArrayList to remove that particular brick.
Remember:
When you are calculating coordinates, the x coordinate is the distance from the left and the y
coordinate is the distance from the top.
The x, y, width, and height data fields are all inherited from Rectangle. Do not redefined them;
if you do, the intersects() method will probably not work correctly.
Since Breakout is a subclass of Applet, it has access to all of the methods of an Applet. That is
how it can get its width and its height.
Comments and formatting: It is very important that you organize your code to use comments,
constants (when feasible) and correct indenting/whitespace. Please make your variable names
meaningful and use Java conventions for choosing their names (start with lower case).
Code, Applet, and Tester files here:
Tester:
//This program is a more sophisticated implemenation of animation in a Javaapplet.//It creates a
ball and has it bounce around the pane It has code that listens//for keyboard keyboard input (left
and right arrows) and mouse clicks//(left button). It also uses a Timer to control the speed of the
animation
import java.applet.*;import java.awt.*;import java.awt.event.*;import
java.awt.image.ImageObserver;import java.util.*;
import javax.swing.Timer;
5. public class BrickTester extends Applet implements KeyListener{
//constantsprivate final int PADDLE_HEIGHT = 5; //height of the paddleprivate final int
PADDLE_WIDTH = 150; //width of the paddleprivate final int PADDLE_MOVE = 20; //how
many pixels to move the
paddle at a time (speed)
private final int BALLDIAMETER = 30; //diameter of the ballprivate final Color
BALLCOLOR = Color.GREEN; //color of the ballprivate final int DELAY = 45;
//number of
milliseconds until timer goes off again
private final Color WALLCOLOR = Color.ORANGE; //Walls' color
private final int WALLWIDTH = 5; //Walls' width
private final int NUMROWS = 3;private final int BRICKSPERROW = 8;private final int
BRICKHEIGHT = 120;private final int TOPSPACE = 125;
//keeps track of whether or not left, right arrow keys are being pressed private boolean
leftPressed; //left arrow key pressed? private boolean rightPressed; //right arrow key pressed?
//graphical components private Paddle thePaddle; private Ball theBall; private Wall leftWall;
private Wall rightWall; private Wall topWall; private Wall bottomWall;
//TO TEST THE BRICKS...create 4 variables that will hold different bricks. //They are all
defined to hold DrawableBricks but we can put in subclasses. private DrawableBrick
testRedBrick; private DrawableBrick testStripedBrick; private DrawableBrick testXBrick;
private DrawableBrick testOvalBrick;
//timer to control the speed private Timer timer;
//init is called when the Applet is first executed - sets it up
public void init(){
//change the size of the applet to be 800 by 600 (minimum guaranteed
screen resolution)
setSize(1200, 800);//fillScreen();
// the next line is required for the keyboard input to work right away
setFocusable(true);
requestFocusInWindow(); // this line might not be necessary, but isgood practice.
//create a Paddle int paddleX = this.getWidth()/2 - PADDLE_WIDTH/2; //x coordinate
is middle of applet
int paddleY = this.getHeight()-WALLWIDTH-10; // y
coordinate is 10 pixels above bottom wall
thePaddle = new Paddle(paddleX, paddleY, PADDLE_WIDTH,
PADDLE_HEIGHT);
6. //create a Ball that starts in the middle of the appletint ballx = getWidth()/2 -
BALLDIAMETER/2;int bally = getHeight()-300;theBall = new Ball(ballx, bally,
BALLDIAMETER, BALLCOLOR);
//create 4 wallsleftWall = new Wall(0, 0, WALLWIDTH, getHeight(),
WALLCOLOR);rightWall = new Wall(getWidth()-WALLWIDTH, 0, WALLWIDTH,
getHeight(), WALLCOLOR);
topWall = new Wall(0, 0, getWidth(), WALLWIDTH, WALLCOLOR);bottomWall = new
Wall(0, getHeight()-WALLWIDTH, getWidth(),
WALLWIDTH, WALLCOLOR);
//TO TEST THE BRICKS...Create 4 different types of DrawableBricks //The variables hold
DrawableBricks but we can put in any subclass. //The x, y, width, height are just made up for this
example... testRedBrick = new RedBrick(5, 300, 275, 100); testStripedBrick = new
StripedBrick(280, 400, 275, 100); testXBrick = new XBrick(555, 500, 275, 100); testOvalBrick
= new OvalBrick(830, 600, 275, 100);
//add a key listener that will respond to key events//(note - since this applet implements
KeyListener, "this" instancecan do it itself)addKeyListener (this); //so it is its own KeyListener
//add a mouse listener that will respond to mouse events
//(note - it will be a new instance of the class defined below)addMouseListener (new
BounceMouseListener());
//create a new Timer to control things and tell it to starttimer = new Timer(DELAY, new
BounceActionListener());timer.start();
//set the background color of this appletthis.setBackground(Color.WHITE);
}
//paint is automatically called with a Graphics object as its argument.
It will
//tell the Graphics object to actually paint things on the pane.//public void paint(Graphics g)//lets
delegate this to the update method instead to fix double buffering
and input issues
public void update(Graphics g){Dimension size = getSize();
Image frameBuffer = createImage(size.width, size.height);Graphics graphicsBuffer =
frameBuffer.getGraphics();
//if left arrow is pressed, move paddle left by 10 pixelsif(leftPressed)
{
if (!thePaddle.intersects(leftWall)){
thePaddle.translate(-1*PADDLE_MOVE, 0);
}
7. }//else if right arrow is pressed, move paddle right by 10 pixelselse if (rightPressed){
if (!thePaddle.intersects(rightWall)){thePaddle.translate(PADDLE_MOVE, 0);}
}//tell each of the walls to set their dimensions (in case the applet
has been resized)
leftWall.setDimensions(0, 0, WALLWIDTH, getHeight());rightWall.setDimensions(getWidth()-
WALLWIDTH, 0, WALLWIDTH,
getHeight());
topWall.setDimensions(0, 0, getWidth(), WALLWIDTH);bottomWall.setDimensions(0,
getHeight()-WALLWIDTH, getWidth(),
WALLWIDTH);
//tell the paddle to set its y coordinate to 10 pixels above bottom
wall
//(in case applet has been resized; note that x coordinate should
not change since paddle
// could be moving).thePaddle.setY(getHeight()-WALLWIDTH-10);
//if the ball hit the left or right wall, tell it to bounce (change
direction)
//if (theBall.intersects(topWall) || theBall.intersects(bottomWall))// theBall.bounce();if
(theBall.intersects(leftWall) || theBall.intersects(rightWall))
theBall.bounceOffSide();else if (theBall.intersects(topWall) ||
theBall.intersects(thePaddle))
theBall.bounceOffTopBottom();else if
(theBall.intersects(bottomWall))theBall.freeze();elsetheBall.recordNotBouncing();
//FOR TESTING THE BRICKS AND A DEMO...//If the ball has intersected any one of the test
bricks (check them
one by one)
//then change its color to be MAGENTA. If not, change it back to
the original
//colorif (theBall.intersects(testRedBrick) ||
theBall.intersects(testStripedBrick) ||
theBall.intersects(testXBrick) ||
theBall.intersects(testOvalBrick))
theBall.setColor(Color.MAGENTA); else theBall.setColor(BALLCOLOR);
//tell the ball to movetheBall.move();
//tell each of the walls to draw themselves using Graphics object
gleftWall.draw(graphicsBuffer);
8. rightWall.draw(graphicsBuffer);topWall.draw(graphicsBuffer);bottomWall.draw(graphicsBuffer
);
//tell the paddle to draw itself using Graphics object gthePaddle.draw(graphicsBuffer);
//tell all 4 test bricks to draw themselves. Even though the
variables are
//originally defined to hold DrawableBricks, they hold different
subclasses
//and Java will wait until runtime to decide the correct .draw
method to call. testRedBrick.draw(graphicsBuffer); testStripedBrick.draw(graphicsBuffer);
testXBrick.draw(graphicsBuffer); testOvalBrick.draw(graphicsBuffer);
//tell the Ball to draw itself using Graphics object gtheBall.draw(graphicsBuffer);
//draw the buffered image on the "real" Applet (this)g.drawImage(frameBuffer, 0, 0, this);
}
//resizes the applet to fill the entire screenprivate void fillScreen(){ Dimension ScreenSize =
Toolkit.getDefaultToolkit().getScreenSize(); Dimension FrameSize = this.getSize(); int xheight
= ScreenSize.height; int xwidth = ScreenSize.width; resize(xwidth, xheight);
//setResizable(false); ///int x = (ScreenSize.width - FrameSize.width)/2; //int y =
(ScreenSize.height - FrameSize.height)/2; //this.setLocation(x, y);
}
//if a key is pressed, see if it is left or right arrow.public void keyPressed(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_LEFT)
leftPressed = true;
else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
rightPressed = true;
}
//if a key is released, see if it was left or right arrowpublic void keyReleased(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_LEFT)
leftPressed = false;
else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
rightPressed = false;
}
//only here because its required by interface...public void keyTyped(KeyEvent e) { }
//Represents the mouse listener for the applet private class BounceMouseListener implements
MouseListener {
public void mouseClicked (MouseEvent event)
{
9. if (timer.isRunning()){
if (theBall.isFrozen()){
int ballx = getWidth()/2 - BALLDIAMETER/2;int bally = getHeight()-100;
theBall.reset(ballx, bally, -1*Math.PI/6); theBall.unfreeze();
}
} }
//these are empty definitions for unused event methods public void mouseEntered (MouseEvent
event) { } //
{setBackground(Color.yellow);}
public void mouseExited (MouseEvent event) { } //
{setBackground(Color.magenta);}
public void mousePressed (MouseEvent event) {} public void mouseReleased (MouseEvent
event) {}
}
//represents the action listener for the timer private class BounceActionListener implements
ActionListener
{
public void actionPerformed (ActionEvent event)
{
//repaint the screen repaint();
}
}
//-----------------------------------------------------------------------//Wall - represents a "Wall,"
which is around the edge of the appletclass Wall extends Rectangle{
//data - most inherited from Rectangleprivate Color color; //its color
//constructorpublic Wall(int x, int y, int theWidth, int theHeight, Color
theColor){
this.x = x;this.y = y;this.width = theWidth;this.height = theHeight;this.color = theColor;
}
//setDimensions - sets the dimensions to whatever is passed inpublic void setDimensions(int x,
int y, int theWidth, int theHeight){
this.x = x;this.y = y;this.width = theWidth;this.height = theHeight;
}//draw - tells the Ball to draw itself, using the Graphics object
received
public void draw(Graphics g){
Color prevColor = g.getColor(); //save previous color
10. associated with g
g.setColor(this.color);g.fillRect(x, y, width, height);g.setColor(prevColor);
//restore
previous color }}
}
Applet:
//This program is a more sophisticated implemenation of animation in a Javaapplet.//It creates a
ball and has it bounce around the pane It has code that listens//for keyboard keyboard input (left
and right arrows) and mouse clicks//(left button). It also uses a Timer to control the speed of the
animation
import java.applet.*;import java.awt.*;import java.awt.event.*;import
java.awt.image.ImageObserver;import java.util.*;
import javax.swing.Timer;
public class Breakout extends Applet implements KeyListener{
//constantsprivate final int PADDLE_HEIGHT = 5; //height of the paddleprivate final int
PADDLE_WIDTH = 150; //width of the paddleprivate final int PADDLE_MOVE = 20; //how
many pixels to move the
paddle at a time (speed)
private final int BALLDIAMETER = 40; //diameter of the ballprivate final Color
BALLCOLOR = Color.GREEN; //color of the ballprivate final int DELAY = 35;
//number of
milliseconds until timer goes off again
private final Color WALLCOLOR = Color.ORANGE; //Walls' color
private final int WALLWIDTH = 5; //Walls' width
//keeps track of whether or not left, right arrow keys are being pressed private boolean
leftPressed; //left arrow key pressed? private boolean rightPressed; //right arrow key pressed?
//graphical components private Paddle thePaddle; private Ball theBall; private Wall leftWall;
private Wall rightWall; private Wall topWall; private Wall bottomWall;
//timer to control the speed private Timer timer;
//init is called when the Applet is first executed - sets it up
public void init(){
//change the size of the applet to be 800 by 600 (minimum guaranteed
screen resolution)
setSize(1200, 800);//fillScreen();
// the next line is required for the keyboard input to work right
away
11. setFocusable(true);
requestFocusInWindow(); // this line might not be necessary, but isgood practice.
//create a Paddle int paddleX = this.getWidth()/2 - PADDLE_WIDTH/2; //x coordinate
is middle of applet
int paddleY = this.getHeight()-WALLWIDTH-10; // y
coordinate is 10 pixels above bottom wall
thePaddle = new Paddle(paddleX, paddleY, PADDLE_WIDTH,
PADDLE_HEIGHT);
//create a Ball that starts in the middle of the appletint ballx = getWidth()/2 -
BALLDIAMETER/2;int bally = getHeight()-300;theBall = new Ball(ballx, bally,
BALLDIAMETER, BALLCOLOR);
//create 4 wallsleftWall = new Wall(0, 0, WALLWIDTH, getHeight(),
WALLCOLOR);rightWall = new Wall(getWidth()-WALLWIDTH, 0, WALLWIDTH,
getHeight(), WALLCOLOR);
topWall = new Wall(0, 0, getWidth(), WALLWIDTH, WALLCOLOR);bottomWall = new
Wall(0, getHeight()-WALLWIDTH, getWidth(),
WALLWIDTH, WALLCOLOR);
//add a key listener that will respond to key events//(note - since this applet implements
KeyListener, "this" instance
can do it itself)
addKeyListener (this); //so it is its own KeyListener
//add a mouse listener that will respond to mouse events//(note - it will be a new instance of the
class defined below)addMouseListener (new BounceMouseListener());
//create a new Timer to control things and tell it to starttimer = new Timer(DELAY, new
BounceActionListener());timer.start();
//set the background color of this appletthis.setBackground(Color.WHITE);
}
//paint is automatically called with a Graphics object as its argument.
It will
//tell the Graphics object to actually paint things on the pane.//public void paint(Graphics g)//lets
delegate this to the update method instead to fix double buffering
and input issues
public void update(Graphics g){Dimension size = getSize();
Image frameBuffer = createImage(size.width, size.height);Graphics graphicsBuffer =
frameBuffer.getGraphics();
//if left arrow is pressed, move paddle left by 10 pixelsif(leftPressed){
12. if (!thePaddle.intersects(leftWall)){
thePaddle.translate(-1*PADDLE_MOVE, 0);
}
}//else if right arrow is pressed, move paddle right by 10 pixelselse if (rightPressed){
if (!thePaddle.intersects(rightWall)){thePaddle.translate(PADDLE_MOVE, 0);}
}//tell each of the walls to set their dimensions (in case the applet
has been resized)
leftWall.setDimensions(0, 0, WALLWIDTH, getHeight());rightWall.setDimensions(getWidth()-
WALLWIDTH, 0, WALLWIDTH,
getHeight());
topWall.setDimensions(0, 0, getWidth(), WALLWIDTH);bottomWall.setDimensions(0,
getHeight()-WALLWIDTH, getWidth(),
WALLWIDTH);
//tell the paddle to set its y coordinate to 10 pixels above bottom
wall
//(in case applet has been resized; note that x coordinate should
not change since paddle
// could be moving).thePaddle.setY(getHeight()-WALLWIDTH-10);
//if the ball hit the left or right wall, tell it to bounce (change
direction)
//if (theBall.intersects(topWall) || theBall.intersects(bottomWall))// theBall.bounce();if
(theBall.intersects(leftWall) || theBall.intersects(rightWall))
theBall.bounceOffSide();else if (theBall.intersects(topWall) ||
theBall.intersects(bottomWall))
theBall.bounceOffTopBottom();else if
(theBall.intersects(thePaddle))theBall.freeze();elsetheBall.recordNotBouncing();
//tell the ball to movetheBall.move();
//tell each of the walls to draw themselves using Graphics object
gleftWall.draw(graphicsBuffer);rightWall.draw(graphicsBuffer);topWall.draw(graphicsBuffer);b
ottomWall.draw(graphicsBuffer);
//tell the paddle to draw itself using Graphics object gthePaddle.draw(graphicsBuffer);
//tell the Ball to draw itself using Graphics object gtheBall.draw(graphicsBuffer);
//drawing the buffered image into the appletg.drawImage(frameBuffer, 0, 0, this);
}
//resizes the applet to fill the entire screenprivate void fillScreen(){ Dimension ScreenSize =
Toolkit.getDefaultToolkit().getScreenSize(); Dimension FrameSize = this.getSize(); int xheight
13. = ScreenSize.height; int xwidth = ScreenSize.width; resize(xwidth, xheight);
//setResizable(false); ///int x = (ScreenSize.width - FrameSize.width)/2; //int y =
(ScreenSize.height - FrameSize.height)/2; //this.setLocation(x, y);
}
//if a key is pressed, see if it is left or right arrow.public void keyPressed(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_LEFT)
leftPressed = true;
else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
rightPressed = true;
}
//if a key is released, see if it was left or right arrowpublic void keyReleased(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_LEFT)
leftPressed = false;
else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
rightPressed = false;
}
//only here because its required by interface...public void keyTyped(KeyEvent e) { }
//Represents the mouse listener for the applet private class BounceMouseListener implements
MouseListener {
public void mouseClicked (MouseEvent event) {
if (timer.isRunning()) timer.stop(); else timer.start();
}
//these are empty definitions for unused event methods public void mouseEntered (MouseEvent
event) { } public void mouseExited (MouseEvent event) { }
//setBackground(Color.magenta);}
public void mousePressed (MouseEvent event) {} public void mouseReleased (MouseEvent
event) {}
}
//represents the action listener for the timer private class BounceActionListener implements
ActionListener
{
public void actionPerformed (ActionEvent event)
{
//repaint the screen repaint();
}
}
14. //-----------------------------------------------------------------------//Wall - represents a "Wall,"
which is around the edge of the appletclass Wall extends Rectangle{
//data - most inherited from Rectangleprivate Color color; //its color
//constructorpublic Wall(int x, int y, int theWidth, int theHeight, Color
theColor){
this.x = x;this.y = y;this.width = theWidth;this.height = theHeight;this.color = theColor;
}//setDimensions - sets the dimensions to whatever is passed in
public void setDimensions(int x, int y, int theWidth, int theHeight){
this.x = x;this.y = y;this.width = theWidth;this.height = theHeight;
}//draw - tells the Ball to draw itself, using the Graphics object
received
public void draw(Graphics g){
Color prevColor = g.getColor(); //save previous color
associated with g
g.setColor(this.color);g.fillRect(x, y, width, height);g.setColor(prevColor);
//restore
previous color }}
}
Ball Code:
//Ball - represents a "Ball" (which is a subclass of Rectangle so it candetermine .intersects)
import java.awt.*;
public class Ball extends Rectangle{
//data - most inherited from Rectangleprivate double angle; //will determine what angle it
travelsprivate Color color; //its colorprivate boolean frozen; //whether or not it is
"frozen"private boolean currentlyBouncing; //remember if it is in a bounce;
otherwise can get "stuck"//constructor
public Ball(int x, int y, int diameter, Color theColor){
this.x = x;this.y = y;this.width = diameter;this.height = diameter;this.color = theColor;this.angle
= -1*Math.PI/7; //add to position each time (so
travelling diagonally)
this.frozen = false; //not frozen
}
//draw - tells the Ball to draw itself, using the Graphics object receivedpublic void
draw(Graphics g){Color prevColor = g.getColor(); //save previous color associated
with g
g.setColor(this.color);g.fillOval(x, y, width, height);g.setColor(prevColor);
15. //restore previous
color }
//bounce - tells it to reverse direction if it hits the top or the bottom public void
bounceOffSide(){
if (!currentlyBouncing){
this.angle = Math.PI - this.angle;
currentlyBouncing = true;}
}
//bounceInverse - tells it to reverse directionpublic void bounceOffTopBottom(){
if (!currentlyBouncing){
this.angle = -1 * this.angle;currentlyBouncing = true;
}
}
//recordNotBouncing - this is necessary because a Ball can become//"stuck" bouncing against a
wall because of timing issues. The program//rechecks to see if has intersected with a wall before
it has "cleared"//the wall from the previous bouncepublic void recordNotBouncing()
{
currentlyBouncing = false;
}
//move - changes its coordinate(s) if its not "frozen"public void move(){
if (!frozen) {
//translates itself by r*cos in the x direction, r*sin in the
Y direction
translate( (int)((10*Math.cos(angle))),
(int)((10*Math.sin(angle))) ); //x = (int)(x + (10*Math.cos(angle))); //equivalent to
these (translate is inherited method)
//y = (int)(y + (10*Math.sin(angle)));
}
}
//setColor - sets its color to whatever is passed in public void setColor(Color newColor) {
this.color = newColor;
}
//freeze() - tells the ball to "freeze" (stops movement). public void freeze() {
frozen = true;
}
//unfreeze() - tells the ball to "unfreeze" (movement is continued) public void unfreeze() {
16. frozen = false;
}
//isFrozen() - returns true if the ball is currently frozen public boolean isFrozen() {
return frozen;
}
//reset - resets its x, y, and angle public void reset(int newX, int newY, double newAngle) {
x = newX; y = newY; angle = newAngle;
}
}
Paddle Code:
//Paddle is the paddle that goes with breakout import java.awt.*; public class Paddle extends
Rectangle
{ //data - all is inherited from Rectangle
//constructor public Paddle(int x, int y, int width, int height) {
this.x = x; this.y = y; this.width = width; this.height = height;
} //setY - sets its Y value to whatever is passed in (in case applet was
resized)
public void setY(int newY) { this.y = newY; }
//draw - tells the Paddle to draw itself, using the Graphics object
received
public void draw(Graphics g) {
Color prevColor = g.getColor(); g.setColor(Color.BLACK); g.fillRect(x, y, width, height);
g.setColor(prevColor);
}
}
Red Brick Code:
import java.awt.*;import java.util.*;
public class RedBrickEXAMPLE extends DrawableBrick{
//data - all is inherited
//constructorpublic RedBrick(int initX, int initY, int initWidth, int initHeight){
this.x = initX;this.y = initY;this.width = initWidth;this.height = initHeight;//super(initX, initY,
initWidth, initHeight);Random gen = new Random();int redpart = gen.nextInt(155) + 100;
//some shade of red
(generates 100-255)
color = new Color(redpart, 0, 0);
}
17. //methodspublic void draw(Graphics g){
Color prevColor = g.getColor(); //save previous color associated
with g
g.setColor(this.color);g.fillRect(x, y, width, height);g.setColor(Color.BLACK);g.drawRect(x, y,
width, height);g.drawLine(x, y, x+width, y+height); //draws a diagonal line -
just as an example...
g.setColor(prevColor);
//restore previous
color}}
Solution
import java.awt.*;
import java.applet.*;
import java.lang.Math;
import java.net.InetAddress;
public class Breakout extends Applet implements Runnable {
public static final int HEIGHT=320, WIDTH=320, SLEEPTIME = 5, //5
BALLRADIUS=5, BLOCKWIDTH = 40, BLOCKHEIGHT = 10,
PADDLEWIDTH = 40, PADDLEHEIGHT=10, PADDLEALTITUDE=HEIGHT-20,
PADDLESPEED=3, BLOCKSPACING_Y=2, BLOCKSPACING_X=2,
MAXBALLS=3;
public static final double INITSPEED_X=2.5, INITSPEED_Y=-2.5, //2.5
XHIT_CHANGE=0.4, YHIT_CHANGE=0.2;
public static final Color PADDLECOLOR=Color.black,
BALLCOLOR=Color.red;
public static final Color BACKGROUND = new Color(0xcccccc);
public static final String BEEP_SOUND = "beep.au";
private boolean paused=false;
private int numberlost=0;
private Graphics gContext;
private Image buffer;
private Thread animate;
private boolean leftArrow = false, rightArrow = false, ballready = true;
private Ball ball;
private BlockHolder blocks;
18. private AudioClip hitsound;
private Paddle paddle;
public void init() {
hitsound = getAudioClip(getDocumentBase(), BEEP_SOUND);
hitsound.play();
buffer = createImage(WIDTH, HEIGHT);
gContext = buffer.getGraphics();
gContext.setColor(BACKGROUND);
blocks = new BlockHolder();
paddle = new Paddle();
ball = new Ball(blocks, hitsound);
gContext.fillRect(0, 0, WIDTH, HEIGHT);
paddle.draw(gContext);
ball.draw(gContext);
blocks.draw(gContext);
}
public void start() {
if(animate == null) {
animate = new Thread(this);
animate.start();
}
}
public void restart() { }
public void stop() {
if(animate != null) {
animate.stop();
animate = null;
}}
public void paint(Graphics g) {
try {
g.drawImage(buffer, 0, 0, this);
}
catch(Exception e) {}
}
public void run() {
try {
22. prepareBlocks();
}
public void restart() {
blockCount=0;
for(int i = 0; i= y && lines[i].top <= y) {
Block hit=lines[i].whohit(x);
if(hit!=null)
blockCount-=1;
return hit;
}
}
return null;
}
public void draw(Graphics g) {
for(int i = 0; i numberblocks)
numhit = numberblocks;
if(exists[numhit]) {
exists[numhit] = false;
return blocks[numhit];
}
return null;
}
}
class Block {
public int x, y;
protected Color color;
protected int width, height;
public Block(int x0, int y0, Color color0) {
x = x0;
y = y0;
color = color0;
width = Breakout.BLOCKWIDTH-Breakout.BLOCKSPACING_X/2;
height = Breakout.BLOCKHEIGHT-Breakout.BLOCKSPACING_Y/2;
}
23. public void clear(Graphics g) {
g.setColor(Breakout.BACKGROUND);
g.fillRect(x,y,width,height);
}
public void draw(Graphics g) {
g.setColor(color);
g.fillRect(x,y, width, height);
}
public int getTop() {
return y;
}
public int getBottom() {
return y+height;
}
public int getleftx() {
return x;
}
public int getrightx() {
return x + width;
}
}
class Paddle extends Block {
public boolean moved = false;
public Paddle() {
super(Breakout.WIDTH/2-Breakout.PADDLEWIDTH/2,
Breakout.PADDLEALTITUDE,
Breakout.PADDLECOLOR);
width = Breakout.PADDLEWIDTH;
height = Breakout.PADDLEHEIGHT;
}
/* Place block on (x0, y0) */
public void go(int x0, int y0) {
x=x0;
y=y0;
}
24. public void move(int change) {
if((x+width < Breakout.WIDTH || change < 0) && (x > 0 || change > 0)) {
x = x + change;
moved = true;
}
else
moved = false;
}
}
class Ball {
public double xchange, ychange;
private double x, y;
private int radius;
private Color color;
private BlockHolder blocks;
private AudioClip beep;
public Ball(BlockHolder blocks0, AudioClip beep0) {
xchange = 0;
ychange = 0;
radius = Breakout.BALLRADIUS;
x = Breakout.WIDTH/2-radius;
y = Breakout.PADDLEALTITUDE-5;
color = Breakout.BALLCOLOR;
blocks = blocks0;
beep = beep0;
}
public void go(int x0, int y0) {
x= (double) x0;
y= (double) y0;
xchange=0.0;
ychange=0.0;
}
public void selfMove(Graphics g, Block paddle, Breakout ap) {
if(x+xchange>=Breakout.WIDTH)
xchange=-Math.abs(xchange);