import java.awt.*;
import java.awt.event.*;
/**
A class used to represent smiley face objects.
* Created July, 2003
*/
public class InteractiveSmileyFace implements KeyListener
{
/** location of the Face */
private Point point;
/** direction of motion in x-direction (+1 for left-to-right and -1 for right-to-left) */
private int xDir;
/** direction of motion in y-direction (+1 for top-to-bottom and -1 for bottom-to-top) */
private int yDir;
/** speed at which to increment x and y coordinates */
private int speed;
/** size of the various parts of the face */
private int radius;
/** relative size of the various parts of the face */
private static final double EYE_RATIO = 1.0 / 4.0,
EYE_BALL_RATIO = 1.0 / 10.0,
X_MOUTH_RATIO = 2.0 / 3.0,
Y_MOUTH_RATIO = 1.0 / 4.0,
FACE_HEIGHT_RATIO = 3.0 / 2.0;
/**
* Constructor: creates an instance of an InteractiveSmileyFace.
* @param xLoc x coordinate of smiley face
* @param yLoc y coordinate of smiley face
* @param aRadius size of smiley face
* @param aSpeed speed at which smiley face moves when animated
*/
public InteractiveSmileyFace( int xLoc, int yLoc, int aRadius, int aSpeed )
{
point = new Point( xLoc, yLoc );
radius = aRadius;
speed = aSpeed;
xDir = 1;
yDir = 1;
}
/**
* Method to set the directions.
* @param xDirection the direction of motion in the x-direction (+1 for left-to-right and -1 for right-to-left)
* @param yDirection the direction of motion in the y-direction (+1 for top-to-bottom and -1 for bottom-to-top)
*/
public void setDirection( int xDirection, int yDirection )
{
xDir = xDirection;
yDir = yDirection;
}
/**
* Method to move the face. If the face goes out of bounds then it changes direction.
* @param xBound width of area in which animation occurs
* @param yBound height of area in which animation occurs
*/
public void move( int xBound, int yBound )
{
point.x = point.x + speed * xDir;
point.y = point.y + speed * yDir;
if( ( point.x > ( xBound - radius ) ) || ( point.x < 0 ) )
{
xDir = xDir * -1;
}
if( ( point.y > ( yBound - (int) ( radius * FACE_HEIGHT_RATIO ) ) )
|| ( point.y < 0 ) )
{
yDir = yDir * -1;
}
}
/**
* Method to draw the face at a specific location. This method will set the location
* of the smiley face and then call the other draw method (used in Lab2).
* @param g the Graphics object on which the smiley face is to be drawn
* @param xLoc x coordinate of location where smiley face is to be drawn
* @param yLoc y coordinate of location where smiley face is to be drawn
*/
public void draw( Graphics g, int xLoc, int yLoc )
{
point.x = xLoc;
point.y = yLoc;
draw( g );
}
/**
* Method to draw the smiley face at its current location.
* (Used in Lab1).
* @param g the Graphics object on which the smiley face is to be drawn
*/
public void draw( Graphics g )
{
if( point != null )
{
//draw face background
g.setColor( Color.yellow );
g.fillOval(
point.x,
point.y,
radius,
(int) ( radius * FACE_HEIGHT_RATIO ) );
//draw face outline
g.setColor( Color.black );
g.drawOval(
point.x,
point.y,
radius,
(int) ( radius * FACE_HEIGHT_RATIO ) );
//draw eye background
g.setColor( Color.white );
g.fillOval(
(int) ( point.x + radius / 2 - radius * EYE_RATIO ),
(int) ( point.y + radius / 3 - radius * EYE_RATIO ),
(int) ( radius * EYE_RATIO ),
(int) ( radius * EYE_RATIO ) );
g.fillOval(
(int) ( point.x + radius / 2 ),
(int) ( point.y + radius / 3 - radius * EYE_RATIO ),
(int) ( radius * EYE_RATIO ),
(int) ( radius * EYE_RATIO ) );
//draw eye outline
g.setColor( Color.black );
g.drawOval(
(int) ( point.x + radius / 2 - radius * EYE_RATIO ),
(int) ( point.y + radius / 3 - radius * EYE_RATIO ),
(int) ( radius * EYE_RATIO ),
(int) ( radius * EYE_RATIO ) );
g.drawOval(
(int) ( point.x + radius / 2 ),
(int) ( point.y + radius / 3 - radius * EYE_RATIO ),
(int) ( radius * EYE_RATIO ),
(int) ( radius * EYE_RATIO ) );
//draw eyeball
g.fillOval(
(int) ( point.x + radius / 2 - radius * EYE_BALL_RATIO ),
(int) ( point.y + radius / 3 - radius * EYE_BALL_RATIO ),
(int) ( radius * EYE_BALL_RATIO ),
(int) ( radius * EYE_BALL_RATIO ) );
g.fillOval(
(int) ( point.x + radius / 2 + radius * EYE_BALL_RATIO ),
(int) ( point.y + radius / 3 - radius * EYE_BALL_RATIO ),
(int) ( radius * EYE_BALL_RATIO ),
(int) ( radius * EYE_BALL_RATIO ) );
//draw mouth
g.setColor( Color.white );
g.fillRect(
(int) ( point.x + radius / 2 - radius * X_MOUTH_RATIO / 2 ),
(int) ( point.y + radius / 2 ),
(int) ( radius * X_MOUTH_RATIO ),
(int) ( radius * Y_MOUTH_RATIO ) );
g.setColor( Color.black );
g.drawRect(
(int) ( point.x + radius / 2 - radius * X_MOUTH_RATIO / 2 ),
(int) ( point.y + radius / 2 ),
(int) ( radius * X_MOUTH_RATIO ),
(int) ( radius * Y_MOUTH_RATIO ) );
}
}
/**
* KeyPressed method used to react to user keyboard input by changing direction of motion of smiley face
*/
public void keyPressed( KeyEvent event )
{
// determine which key was pressed
char key = event.getKeyChar();
// if the key is equal to 'i' then set the direction of motion in the y-direction to bottom-to-top
if( key == 'i' )
{
yDir = -1;
}
// ADD CODE BELOW TO CHANGE THE DIRECTION OF MOTION TO TOP-TO-BOTTOM
// LEFT-TO-RIGHT AND RIGHT-TO-LEFT WHEN OTHER KEYS ARE PRESSED
// if the key is equal to 'm' then set the direction of motion in the y-direction to top-to-bottom
if( key == 'm' )
{
yDir = 1;
}
// if the key is equal to 'j' then set the direction of motion in the x-direction to right-to-left
if( key == 'j' )
{
xDir = -1;
}
// if the key is equal to 'l' then set the direction of motion in the x-direction to left-to-right
if( key == 'l' )
{
xDir = 1;
}
}
public void keyReleased( KeyEvent event )
{
// do nothing when a key is released
}
public void keyTyped( KeyEvent event )
{
// do nothing when a key is typed
}
}