Java Reference
In-Depth Information
Let us first examine the key listener. The
getKeyCode
method returns an integer that is
associated with the pressed key. We could not use the
getKeyChar
method because there are
no characters that are associated with the arrow keys (and even if there were, we do not know
how to refer to them). The
KeyEvent
class stores the code of most virtual keys as constants.
For example,
KeyEvent.VK LEFT
is the left arrow. The code changes the coordinates of the
paddle by calling the
moveLeft
or
moveRight
method and then it refreshes the panel.
Note that we could have also rewritten the code as follows.
String s= KeyEvent . getKeyText ( e . getKeyCode () ) ;
if
(s.equals(
"Left"
))
{
...
}
The
getKeyText
method converts the key code to text. However, this is an inferior solution
because it assumes that the string
Left
will be returned. For example, nothing stops Java
from returning the string
LEFT
in future implementations.
Note that the panel needs to be made focusable in order for the key listener to work.
Only components that have the focus can receive key events and by default the panel is not
focusable. The call
setFocusable(true)
makes the panel focusable.
The mouse listener is a little more interesting than the key listener. It saves the old
position of the mouse cursor and it compares it with the new position of the mouse cursor.
The paddle is moved by the value of the difference of the two numbers. This means that if
we move the mouse fast, then the paddle will be moved fast as well. Of course, we do not
know the old value of the cursor the first time we move the mouse. Therefore, we need an
extra variable and an
if
statement to address this special case. Finally, note that we can
use the mouse to move the paddle only when the cursor is inside the panel. The reason is
that mouse events are reported to a component only while the mouse cursor is over that
component.
If we run the program that we have so far, we will note that everything works except
that the ball goes right though the paddle. The reason is that we have not added code
that bounces the ball off the paddle. We will add this code in the time listener inside the
BreakoutPanel
class. Our code will create a
virtual ball
that predicts were the ball will go
next without actually moving the ball. We will then check to see if the virtual ball intersects
the paddle. The reason a virtual ball is created is because we want to change the trajectory
of the ball before it overlaps with the paddle. If the virtual ball intersects the paddle, then
we will check if it intersects the left or right part of the paddle. If it intersects the left part
of the paddle, then the ball will bounce to the left. Alternatively, if it intersects the right
part of the paddle, then the ball will bounce to the right. Here is the new version of the
Ball
class that supports the extended interface.
public class
Ball
extends
BreakoutShape
{
private static final int
SIZE = 10;
private static final int
START X = 200;
private static final int
START Y = 400;
private
BreakoutPanel panel ;
private int
dx = 1;
private int
dy =
−
1;
public
Ball (Color color ,BreakoutPanel panel)
{
super
(
new
Ellipse2D.Double(Ball .STARTX, B a l l . START Y, Ball .SIZE ,
Ball .SIZE) , color ,
true
);
this
. panel = panel ;
}