//William Brownlow Final Exam Project
import java.awt.event.*;
import java.awt.*;
import java.applet.Applet;
public class tennis extends Applet implements Runnable, MouseListener, MouseMotionListener
{
static final int statusBarHt=20;
static final int minSleepTime=20;
static final int openingScreen=1;
static final int fadeOut=2;
static final int gameOver=3;
static final int limbo=4;
static final int normalPlay=5;
static final int ballDiameter=10;
static final int maxBallVelocity=10;
static final int paddleHt=50;
static final int paddleWidth=7;
static final int serveBall=10;
static final int you=0;
static final int pc=1;
static final double lookForBallFreq=1;
static final int X=0;
static final int Y=1;
static final int oldX=2;
static final int oldY=3;
static int gameMode=openingScreen;
long startTime;
int height,width; // height & width of applet
int yStatusBar,topStatusBar;
int sleepTime; // value used for sleep with thread
int fadeCt; // counter for creating fadeOut
int yPaddle[],xPaddle[],yPaddleOld[],paddleScore[];
int ball[],ballsUsed,maxBalls;
int yPaddleMax,ballVelocity[];
int yPaddleVelocityPc=10;
int lastPoint=pc;
int timeToServe=0;
int xMidCourt;
boolean ballInPlay;
Thread myThread=null;
Image offScrImage;
Graphics offScrGraphics;
FontMetrics fontMetrics;
Rectangle rBall;
Rectangle paddle[]=new Rectangle[2];
public void init()
{
String s;
int i;
width=600;
height=400;
xMidCourt=width/2;
yStatusBar=height - (statusBarHt/4);
topStatusBar=height-statusBarHt;
sleepTime= 50;
maxBalls= 46;
ball=new int[4];
ballVelocity=new int[2];
yPaddleMax=topStatusBar-paddleHt;
yPaddle=new int[2];
xPaddle=new int[2];
xPaddle[you]=15;
xPaddle[pc]=width-paddleWidth-xPaddle[you];
yPaddleOld=new int[2];
paddleScore=new int[2];
offScrImage = createImage(width, height);
offScrGraphics = offScrImage.getGraphics();
offScrGraphics.setFont(new Font("TimesRoman", Font.BOLD, 16));
fontMetrics = offScrGraphics.getFontMetrics();
addMouseListener(this);
addMouseMotionListener(this);
}
public void createBall()
{
int j=paddleHt/2;
setBallVelocity();
if (lastPoint==pc)
{
ballVelocity[X]*=-1;
ball[X]=ball[oldX]=xPaddle[pc]-ballDiameter;
ball[Y]=ball[oldY]=yPaddle[pc]+j;
}
else
{
ball[X]=ball[oldX]=xPaddle[you]+paddleWidth;
ball[Y]=ball[oldY]=yPaddle[you]+j;
}
ballInPlay=true;
timeToServe=0;
}
public void setBallVelocity()
{
double i;
i= Math.random()*1;
if (i > .5) i=1;
else i=-1;
ballVelocity[X]=(int)((Math.random()*maxBallVelocity)+5);
ballVelocity[Y]= (int)(i) * (int)((Math.random()*maxBallVelocity)+5);
}
public void start()
{
startTime=System.currentTimeMillis();
if (myThread==null)
{
myThread= new Thread(this);
myThread.start();
}
}
public void stop()
{
myThread.stop();
myThread=null;
gameMode=gameOver;
}
public void run()
{
while (myThread !=null)
{
repaint();
try {
myThread.sleep(Math.max(startTime-System.currentTimeMillis(),minSleepTime));
}
catch (InterruptedException e) {
}
startTime=System.currentTimeMillis()+sleepTime;
}
}
public void showNormalPlay()
{
int i,j=0;
if (ballInPlay)
{
// erase paddles
offScrGraphics.setColor(Color.green);
for (i=0; i<2; i++)
{
// do not erase top of scoreBar
offScrGraphics.fillRect(xPaddle[i],yPaddleOld[i],paddleWidth,paddleHt);
}
// erase ball
offScrGraphics.fillRect(ball[oldX],ball[oldY],ballDiameter,ballDiameter);
// set new paddle[pc] position
// first check if ball is above or below PC paddle
if (ballVelocity[X] > 0 && ball[X] > xMidCourt && Math.random() <= lookForBallFreq)
{
if (ballVelocity[Y] > 0 && ball[Y] + ballDiameter > yPaddle[pc])
j=Math.abs(yPaddleVelocityPc);
else if (ballVelocity[Y] < 0 && ball[Y] < yPaddle[pc]+paddleHt)
j=-1 * (Math.abs(yPaddleVelocityPc));
}
if (yPaddle[pc]+j <= 0 || yPaddle[pc]+j >= topStatusBar-paddleHt)
j*=-1;
yPaddle[pc]+=j;
// draw paddles
offScrGraphics.setColor(Color.blue);
for (i=0; i<2; i++)
{
offScrGraphics.fillRect(xPaddle[i],yPaddle[i],paddleWidth,paddleHt);
paddle[i]=new Rectangle(xPaddle[i],yPaddle[i],paddleWidth,paddleHt);
yPaddleOld[i]=yPaddle[i];
}
// set new ball position
// PC wins point
if (ball[X]+ballVelocity[X] < 0)
{
ballsUsed++;
paddleScore[pc]+=15;
lastPoint=pc;
ballInPlay=false;
showNewScore();
}
// I win point
else if (ball[X]+ballVelocity[X] > width-ballDiameter)
{
ballsUsed++;
paddleScore[you]+=15;
lastPoint=you;
ballInPlay=false;
showNewScore();
}
else
{
if (ball[Y]+ballVelocity[Y] < 0 || ball[Y]+ballDiameter+ballVelocity[Y] > topStatusBar-ballDiameter)
ballVelocity[Y]*=-1;
rBall=new Rectangle(ball[X]+ballVelocity[X],ball[Y]+ballVelocity[Y],ballDiameter,ballDiameter);
if (rBall.intersects(paddle[you])) setBallVelocity();
else if (rBall.intersects(paddle[pc]))
{
setBallVelocity();
ballVelocity[X]*=-1;
}
ball[X]+=ballVelocity[X];
ball[Y]+=ballVelocity[Y];
ball[oldX]=ball[X];
ball[oldY]=ball[Y];
offScrGraphics.setColor(Color.white);
offScrGraphics.fillOval(ball[X],ball[Y],ballDiameter,ballDiameter);
}
}
else timeToServe++;
if (paddleScore[you] >=maxBalls || paddleScore[pc] >= maxBalls)
{
gameMode=fadeOut;
fadeCt=0;
}
if (timeToServe == serveBall) createBall();
}
public void showNewScore()
{
offScrGraphics.setColor(Color.magenta);
offScrGraphics.fillRect(0,height-statusBarHt,width,statusBarHt);
offScrGraphics.setColor(Color.cyan);
offScrGraphics.drawString("You: "+paddleScore[you],10,yStatusBar);
offScrGraphics.drawString("PC: "+paddleScore[pc],width-60,yStatusBar);
}
public void showOpeningScreen()
{
String buf;
int i;
int j=height/2;
offScrGraphics.setColor(Color.white);
offScrGraphics.fillRect(0,0,width,height);
offScrGraphics.setColor(Color.blue);
buf="Play tennis against the machine!";
offScrGraphics.drawString(buf,(width-fontMetrics.stringWidth(buf))/2,j-50);
offScrGraphics.setColor(Color.magenta);
buf="Click on mouse to begin game.";
offScrGraphics.drawString(buf,(width-fontMetrics.stringWidth(buf))/2,j);
buf="Move mouse to control paddle.";
offScrGraphics.drawString(buf,(width-fontMetrics.stringWidth(buf))/2,j+25);
gameMode=limbo;
ballInPlay=false;
ballsUsed=0;
timeToServe=0;
return;
}
public void showScoreBoard()
{
String buf;
int i,k;
int j=height/2;
offScrGraphics.setColor(Color.white);
offScrGraphics.fillRect(0,0,width,height);
buf="You - PC";
k=(width-fontMetrics.stringWidth(buf))/2;
offScrGraphics.setColor(Color.blue);
offScrGraphics.drawString(buf, k,j - 65);
offScrGraphics.setColor(Color.magenta);
buf="Click on mouse to begin game.";
offScrGraphics.drawString(buf,(width-fontMetrics.stringWidth(buf))/2,j+50);
gameMode=limbo;
paddleScore[you]=paddleScore[pc]=ballsUsed=0;
timeToServe=0;
return;
}
public void showFadeOut()
{
int i;
int j=topStatusBar/2;
fadeCt+=4;
offScrGraphics.setColor(Color.black);
if (fadeCt <= j)
{
offScrGraphics.fillRect(0,j-fadeCt ,width,4);
offScrGraphics.fillRect(0,j+fadeCt-4,width,4);
}
else
{
offScrGraphics.setColor(Color.green);
offScrGraphics.fillRect(0,0,width,topStatusBar);
if (ballsUsed >= maxBalls) gameMode=gameOver;
else gameMode=normalPlay;
showNewScore();
}
return;
}
/* public boolean handleEvent(Event e)
{
if (e.id == Event.MOUSE_DOWN)
{
if (gameMode==limbo)
{
gameMode=fadeOut;
fadeCt=0;
}
}
return super.handleEvent(e);
}
*/
public void mouseMoved( MouseEvent e )
{
if (e.getY() < 0)
yPaddle[you]=0;
else if (e.getY() > yPaddleMax) yPaddle[you]=yPaddleMax;
else yPaddle[you]=e.getY();
}
public void mouseExited( MouseEvent e ) {}
public void mouseDragged( MouseEvent e ) {}
public void mousePressed( MouseEvent e ) {}
public void mouseReleased( MouseEvent e ) {}
public void mouseEntered( MouseEvent e ) {
if (gameMode==limbo)
{
gameMode=fadeOut;
fadeCt=0;
}
}
public void mouseClicked( MouseEvent e )
{
}
public void update (Graphics g)
{
if (gameMode != limbo)
{
if (gameMode==fadeOut) showFadeOut();
else if (gameMode==gameOver) showScoreBoard();
else if (gameMode==openingScreen) showOpeningScreen();
else showNormalPlay();
paint(g);
}
}
public void paint(Graphics g)
{
g.drawImage(offScrImage,0,0,this);
}
}