HW5 Solutions Page
Return to
homework page.
//
// Interface Name: PongClientServerDefines
//
// Purpose: contains defines used by Pong client and server
//
public interface PongClientServerDefines
{
//
// Defines concerning Pong Client Server communication
//
static int SERVERPORT=6542;
static int ENDGAMECODE=7;
static int ENDGAMELENGTH =0;
static int ENDPOINTCODE=3;
static int ENDPOINTLENGTH=30;
static int STARTGAMECODE=5;
static int STARTGAMELENGTH=10;
static int STARTPOINTCODE = 6;
static int STARTPOINTLENGTH = 0;
static int PLAYINGCODE = 127;
static int UPCODE = 0;
static int DOWNCODE = 255;
static int LPLAYER = 1;
static int RPLAYER = 2;
//
// Defines for Initially Positioning Elements on
// Pong Client Screens
//
static int PADDLE_WIDTH = 5;
static int PADDLE_HEIGHT = 30;
static int PREFERRED_WIDTH = 300;
static int PREFERRED_HEIGHT = 200;
static int BALL_RADIUS=5;
static int BALLX = PREFERRED_WIDTH/2+4*BALL_RADIUS;
static int BALLY = PREFERRED_HEIGHT/2;
static int BALLXVEL = 2;
static int BALLYVEL = 2;
static int MAXBALLVEL = 5;
static int MINBALLX = 10;
static int MAXBALLX = PREFERRED_WIDTH-BALL_RADIUS-MINBALLX;
static int MINBALLY = 10;
static int MAXBALLY = PREFERRED_HEIGHT-BALL_RADIUS-MINBALLY;
static int FUDGE = 10;
static int LSCORE_X = PREFERRED_WIDTH/6;
static int RSCORE_X = 5*LSCORE_X, SCORE_Y=25;
static int TEXT_X = 40;
static int TEXT_Y = PREFERRED_HEIGHT/2;
static int LPADDLEX = PADDLE_WIDTH;
static int RPADDLEX = PREFERRED_WIDTH-2*PADDLE_WIDTH;
static int PADDLEY = (PREFERRED_HEIGHT-PADDLE_HEIGHT)/2;
static int MAXPADDLEVEL =5;
static int MINPADDLE = 10;
static int MAXPADDLE = PREFERRED_HEIGHT-MINPADDLE-PADDLE_HEIGHT;
static int MAXSCORE = 10; //score game ends at
}
/**
* PongServer.java
*
* Title: PongServer
* Description: This is the server for our Pong Game
* @author cpollett
* @version
*/
import java.io.*;
import java.net.*;
import java.awt.event.*;
import javax.swing.*;
public class PongServer implements PongClientServerDefines{
ServerSocket server; // TCP listener
Socket pConnection[]; // connection for each player
int pPort[]; // port player will listen to UDP on
DatagramSocket transmitUDP; // used for sending UDP of positions of ball/players
DatagramPacket packetUDP[]; // packet for sending; we reuse this a lot
byte packetData[]; // array of data for packet
DataInputStream pIn[]; // connection input output stream
DataOutputStream pOut[];
int gamePhase; // gives current state of program
int phaseCounter; // used to measure how long have been in current
// state (multiple of 100ms)
int whosePoint=0; // who scored the last point
boolean ack[]; // in non playing phase we expect each player
// to acknowledge our UDP transmissions
// this var keeps track of whose done this
Thread playerThread[]; //thread for managing each players comunication
Timer timerUDP; // timer for UDP broadcasts
int paddle[]; // y position for each player's paddle
int paddleVel[]; // y velocity of each player's paddle
int ballX; // ball x position
int ballY; // ball y position
int ballXVel; // ball X velocity
int ballYVel; // ball Y velocity
int lScore; // left player's score
int rScore; // right player's score
//
// Constructor Name: PongServer
//
// Purpose: initializes threads, timers, and sockets used by our server
//
public PongServer() {
try
{
server = new ServerSocket(SERVERPORT,2);
transmitUDP = new DatagramSocket();
}
catch(Exception se)
{
se.printStackTrace();
System.exit(1);
}
packetUDP = new DatagramPacket[2];
packetData = new byte[8];
pConnection = new Socket[2];
pIn = new DataInputStream[2];
pOut = new DataOutputStream[2];
pPort = new int[2];
ack = new boolean[2];
playerThread = new Thread[2];
paddle = new int[2];
paddleVel = new int[2];
playerThread[0]= new Thread(new Runnable()
{
public void run()
{
playerTCP(0);
}
}
);
playerThread[0].start();
playerThread[1]= new Thread(new Runnable()
{
public void run()
{
playerTCP(1);
}
}
);
playerThread[1].start();
timerUDP = new Timer( 100,
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
broadcastUDP();
}
}
);
}
//
// Method Name: runServer
//
// Purpose: gets a connection from each player
// sets up streams, finds out UDP port player is listening to,
// tells player which paddle he is.
//
public void runServer()
{
int i;
while(true)
{
System.out.println("Server: Waiting for connections...");
try
{
for (i=0; i<2; i++)
{
pConnection[i] = server.accept();
System.out.println("Server: Player"+i+" connected.");
pIn[i] = new DataInputStream( pConnection[i].getInputStream());
pPort[i]=pIn[i].readInt();
packetUDP[i] = new DatagramPacket(packetData,
packetData.length,
pConnection[i].getInetAddress(),
pPort[i]
);
pOut[i] = new DataOutputStream( pConnection[i].getOutputStream());
pOut[i].flush();
System.out.println("Server: Player"+i+" streams set up.");
}
pOut[0].writeInt(LPLAYER);
pOut[1].writeInt(RPLAYER);
}
catch(Exception e)
{
e.printStackTrace();
System.exit(1);
}
startGame();
//main thread now waits until it's time to play again
try
{
synchronized(this)
{
wait();
}
}
catch(Exception e)
{
e.printStackTrace();
System.exit(1);
}
stopGame();
}
}
//
// Method Name: startGame
//
// Purpose: sets up scores, ball, paddle locations as at start of game.
// starts UDP broadcaster timer, tells player thread to process
// to TCP messages.
//
public void startGame()
{
startPoint();
lScore = 0;
rScore = 0;
gamePhase = STARTGAMECODE;
phaseCounter = 0;
timerUDP.start();
//
// Notify player threads that we are going to play a game
//
try
{
synchronized(this)
{
notifyAll();
}
}
catch(Exception e)
{
e.printStackTrace();
System.exit(1);
}
}
//
// Method Name: startGame
//
// Purpose: sets up ball, paddle locations as at start of round.
// ball initial velocity random.
//
public void startPoint()
{
for(int i=0; i<2; i++)
{
paddle[i] = PADDLEY;
paddleVel[i] = 0;
ack[i] = false;
}
ballX = BALLX;
ballY = BALLY;
ballXVel = (Math.random() > .5)? BALLXVEL : -BALLXVEL;
ballYVel = (Math.random() > .5)? BALLYVEL : -BALLYVEL;
}
//
// Method Name: stopGame
//
// Purpose: stops UDP broadcaster thread.
//
public void stopGame()
{
timerUDP.stop();
}
//
// Method Name: broadcastUDP
//
// Purpose: main function for UDP broadcaster timer.
// sends packets to client according to game phase.
//
public void broadcastUDP()
{
switch(gamePhase)
{
case STARTGAMECODE:
phaseHandler(STARTGAMELENGTH, STARTPOINTCODE);
break;
case STARTPOINTCODE:
if(phaseHandler(STARTPOINTLENGTH, PLAYINGCODE))
startPoint();
break;
case ENDPOINTCODE:
phaseHandler(ENDPOINTLENGTH, STARTPOINTCODE);
break;
case ENDGAMECODE:
if(phaseHandler(ENDGAMELENGTH, STARTGAMECODE))
{
try
{
synchronized(this)
{
notify(); // notify main thread game's over
// main thread will stop game
}
}
catch(Exception e)
{
e.printStackTrace();
System.exit(1);
}
}
break;
default:
updateScreen();
}
}
//
// Method Name: phaseHandler
//
// Purpose: for non playing game states write out appropriate
// packet if haven't gotten an acknowledgement yet.
// if both players have acknowledge than start counting
// 100ms blocks for how long this phase is supposed to last
//
public boolean phaseHandler(int phaseLength, int nextPhase)
{
boolean flag =false;
for(int j=0; j < 8; j++)
packetData[j] = (new Integer(gamePhase)).byteValue();
for(int i=0; i < 2; i++)
{
if(!ack[i])
{
try
{
transmitUDP.send(packetUDP[i]);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
if(ack[0] && ack[1])
{
if(phaseCounter < phaseLength)
phaseCounter++;
else
{
ack[0]=false;
ack[1]=false;
gamePhase = nextPhase;
phaseCounter = 0;
flag =true;
}
}
return flag;
}
//
// Method Name: updateScreen
//
// Purpose: games during playing state to update the positions of
// ball/paddles on screen. Check to see if anything went of
// bounds and does appropriate. If ball goes out of
// bound the state is change to either end point or end game.
//
public void updateScreen()
{
ballX += ballXVel;
ballY += ballYVel;
if(ballY < MINBALLY)
{
ballYVel = -ballYVel;
ballY = 10;
}
if(ballY > MAXBALLY)
{
ballYVel = -ballYVel;
ballY = MAXBALLY;
}
if(ballX < MINBALLX+FUDGE && ballY > paddle[0]
&& ballY < paddle[0]+ PADDLE_HEIGHT)
{
ballXVel = -(ballXVel-1);
ballYVel = (ballYVel + paddleVel[0])/2;
}
if(ballX > MAXBALLX-FUDGE && ballY > paddle[1]
&& ballY < paddle[1]+ PADDLE_HEIGHT)
{
ballXVel = -(ballXVel+1);
ballYVel = (ballYVel + paddleVel[1])/2;
}
for(int i=0; i<2; i++)
{
paddle[i] += paddleVel[i];
if(paddle[i] < MINPADDLE)
{
paddle[i] = MINPADDLE;
paddleVel[i] = 0;
}
if(paddle[i] > MAXPADDLE)
{
paddle[i] = MAXPADDLE;
paddleVel[i] = 0;
}
}
if(ballX <MINBALLX)
{
whosePoint = 2;
rScore++;
if(rScore < MAXSCORE)
gamePhase = ENDPOINTCODE;
else
gamePhase = ENDGAMECODE;
}
if(ballX > MAXBALLX)
{
whosePoint = 1;
lScore++;
if(lScore < MAXSCORE)
gamePhase = ENDPOINTCODE;
else
gamePhase = ENDGAMECODE;
}
sendCoords();
}
//
// Method Name: sendCoords
//
// Purpose: function used by updateScreen to convert
// ball/paddle locations into UDP packet data and transmit.
//
//
public void sendCoords()
{
// ball X ccord.
packetData[0]= (new Integer(ballX >> 8)).byteValue();
packetData[1]= (new Integer(ballX & 255)).byteValue();
// ball Y coord
packetData[2]= (new Integer(ballY >> 8)).byteValue();
packetData[3]= (new Integer(ballY & 255)).byteValue();
// left paddle Y
packetData[4]= (new Integer(paddle[0] >> 8)).byteValue();
packetData[5]= (new Integer(paddle[0] & 255)).byteValue();
// right paddle Y
packetData[6]= (new Integer(paddle[1] >> 8)).byteValue();
packetData[7]= (new Integer(paddle[1] & 255)).byteValue();
try
{
for(int i =0; i<2; i++)
{
transmitUDP.send(packetUDP[i]);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
//
// Method Name: playerTCP
//
// Purpose: function used by player thread used to
// manage TCP communication with a player client.
// if game not begun this function causes the thread to wait.
// Once game started thread tries to read from input stream
// In play state this info is used to move the player up or down.
// In other states, the signal is compared to the current
// game state and the game state is echoed to client so
// client know is can ignore last UDP message. If signal
// and game state are equal the appropriate action for that state is
// taken.
//
public void playerTCP(int player)
{
int signal;
while(true)
{
signal = STARTGAMECODE;
try
{
synchronized(this)
{
wait();
}
while(signal != ENDGAMECODE)
{
signal = pIn[player].readInt();
switch(signal)
{
case STARTGAMECODE:
pOut[player].writeInt(gamePhase);
if(gamePhase == signal)
{
ack[player] =true;
}
System.out.println("Player"+player+"acknowledges start game.");
System.out.println(" Game Phase is "+gamePhase+".");
break;
case STARTPOINTCODE:
pOut[player].writeInt(gamePhase);
if(gamePhase == signal)
{
ack[player] =true;
}
System.out.println("Player"+player+"acknowledges start point.");
System.out.println(" Game Phase is "+gamePhase+".");
break;
case ENDPOINTCODE:
pOut[player].writeInt(gamePhase);
if(gamePhase == signal)
{
pOut[player].writeInt(whosePoint);
pOut[player].writeInt(lScore);
pOut[player].writeInt(rScore);
ack[player] =true;
}
System.out.println("Player"+player+"acknowledges end point.");
System.out.println(" Game Phase is "+gamePhase+".");
break;
case ENDGAMECODE:
pOut[player].writeInt(gamePhase);
System.out.println("Player"+player+"acknowledges end game.");
System.out.println(" Game Phase is "+gamePhase+".");
if(gamePhase == ENDGAMECODE)
{
ack[player] =true;
pOut[player].writeInt(whosePoint);
pOut[player].writeInt(lScore);
pOut[player].writeInt(rScore);
pIn[player].close();
pOut[player].close();
pConnection[player].close();
System.out.println("Player"+player+"connection closed.");
}
break;
case UPCODE:
if( - MAXPADDLEVEL < paddleVel[player])
paddleVel[player]--;
break;
case DOWNCODE:
if( paddleVel[player] < MAXPADDLEVEL)
paddleVel[player]++;
break;
}// end switch
}// end while signal
} // end try
catch(Exception e)
{
e.printStackTrace();
System.exit(1);
}
} // end while true
}
// Main entry point
static public void main(String[] args) {
PongServer app = new PongServer();
app.runServer();
}
}
/**
* PongClient.java
*
* Title: Client For Pong Game
* (most of work gets done in this classes frame)
* Description:
* @author cpollett
* @version
*/
import PongFrame;
public class PongClient {
public PongClient() {
try {
PongFrame frame = new PongFrame();
frame.initComponents();
frame.setVisible(true);
}
catch (Exception e) {
e.printStackTrace();
}
}
// Main entry point
static public void main(String[] args) {
new PongClient();
}
}
/**
* PongFrame.java
*
* Title: Client Frame For Pong Game
* Description:
* @author cpollett
* @version
*/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class PongFrame extends java.awt.Frame implements PongClientServerDefines
{
boolean connectMode=false; //tells whether a connection has been established
DatagramSocket listenerUDP; // used to listen for UDP packets
DatagramPacket receivePacket; // reused to receive packets from listener
Socket keySocket; // TCP socket used to send keystroke info to server
DataInputStream in; // it input/output streams
DataOutputStream out;
int player; //holds which player client is.
String msg; // holds message to be printed in PongScreen.
int lScore; // left score to be printed in PongScreen
int rScore; // right score to be printed in PongScreen
int whosePoint; // who scored the last point
int xBall; //ball position
int yBall;
int yL; //left paddle y
int yR; //right paddle y
Thread threadUDP; //thread for handling UDP packets
Thread threadConnect; // auxiliary thread used by connect button
// to do the actual connecting
byte data[];
// IMPORTANT: Source code between BEGIN/END comment pair will be regenerated
// every time the form is saved. All manual changes will be overwritten.
// BEGIN GENERATED CODE
// member declarations
javax.swing.JButton connectButton = new javax.swing.JButton();
javax.swing.JTextField serverURLField = new javax.swing.JTextField();
javax.swing.JLabel serverLabel = new javax.swing.JLabel();
PongPanel pongPanel1 = new PongPanel();
// END GENERATED CODE
//
// Constructor Name: PongFrame
//
// Purpose: initializes threads, and sockets used by our client
//
public PongFrame() {
try
{
listenerUDP = new DatagramSocket();
}
catch(SocketException se)
{
se.printStackTrace();
System.exit(1);
}
data = new byte[ 8 ];
receivePacket = new DatagramPacket(data, data.length);
threadUDP = new Thread(new Runnable()
{
public void run()
{
listenUDP();
}
}
);
threadUDP.start();
threadConnect = new Thread(new Runnable()
{
public void run()
{
listenConnect();
}
}
);
threadConnect.start();
}
//
// Method Name: initComponents
//
// Purpose: automatically generated function from CodeWarrior
// It sets up all the GUI components of our client.
//
public void initComponents() throws Exception {
// IMPORTANT: Source code between BEGIN/END comment pair will be regenerated
// every time the form is saved. All manual changes will be overwritten.
// BEGIN GENERATED CODE
// the following code sets the frame's initial state
connectButton.setSize(new java.awt.Dimension(100, 28));
connectButton.setLocation(new java.awt.Point(360, 40));
connectButton.setVisible(true);
connectButton.setText("Connect");
serverURLField.setSize(new java.awt.Dimension(220, 30));
serverURLField.setLocation(new java.awt.Point(130, 40));
serverURLField.setVisible(true);
serverLabel.setSize(new java.awt.Dimension(100, 30));
serverLabel.setLocation(new java.awt.Point(10, 40));
serverLabel.setVisible(true);
serverLabel.setText("Server URL:");
pongPanel1.setSize(new java.awt.Dimension(300, 200));
pongPanel1.setLocation(new java.awt.Point(90, 90));
pongPanel1.setVisible(true);
pongPanel1.setText("PongClient");
pongPanel1.setLayout(null);
setLocation(new java.awt.Point(0, 0));
setSize(new java.awt.Dimension(511, 335));
setBackground(java.awt.Color.white);
setLayout(null);
setTitle("PongFrame");
add(connectButton);
add(serverURLField);
add(serverLabel);
add(pongPanel1);
connectButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
connectButtonActionPerformed(e);
}
});
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
thisWindowClosing(e);
}
});
addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent e) {
thisKeyTyped(e);
}
});
// END GENERATED CODE
}
private boolean mShown = false;
public void addNotify() {
super.addNotify();
if (mShown)
return;
// move components to account for insets
Insets insets = getInsets();
Component[] components = getComponents();
for (int i = 0; i < components.length; i++) {
Point location = components[i].getLocation();
location.move(location.x, location.y + insets.top);
components[i].setLocation(location);
}
mShown = true;
}
// Close the window when the close box is clicked
void thisWindowClosing(java.awt.event.WindowEvent e) {
setVisible(false);
dispose();
System.exit(0);
}
//
// Method Name: thisKeyTyped
//
// Purpose: called by our KeyListener. If in connected
// writes to server either up or down if the appropriate key pressed
//
public void thisKeyTyped(java.awt.event.KeyEvent e) {
if(connectMode==false) return;
char key = e.getKeyChar();
int output = PLAYINGCODE;
switch(player)
{
case LPLAYER:
if( key == '1') output = UPCODE;
if( key == '2') output = DOWNCODE;
break;
case RPLAYER:
if( key == '9') output = UPCODE;
if( key == '0') output = DOWNCODE;
break;
}
try
{
out.writeInt(output);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
//
// Method Name: connectButtonActionPerformed
//
// Purpose: called when connect button pressed to
// try to establish a connection with a given
// server. It works by notifying the auxiliary thread
// threadConnect. Which continues executing listenConnect()
// below.
//
public void connectButtonActionPerformed(java.awt.event.ActionEvent e) {
if(connectMode==true) return;
pongPanel1.setText("Connecting...");
pongPanel1.repaint();
try
{
synchronized(this)
{
notify();
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
//
// Method Name: listenUDP
//
// Purpose: main function executed by of UDP thread.
// It mainly waits for packets. Then processes
// the information contained in them
//
private void listenUDP()
{
while(true)
{
try
{
listenerUDP.receive(receivePacket);
}
catch(IOException io)
{
System.err.println(io.toString());
}
if(connectMode == true)
{
if(!checkChangeMode())
getCoords();
updateScreen();
pongPanel1.repaint();
}
}
}
//
// Method Name: listenConnect
//
// Purpose: main function executed by our connect thread.
// It excecutes if the mode is not connect mode
// and the connect button has notified it.
// It tries to establish a TCP connection
// with the server in question and sends info
// to server about which port to send packets to.
//
private void listenConnect()
{
while(true)
{
try
{
synchronized(this)
{
wait(); //for connect button
}
}
catch(Exception io)
{
System.err.println(io.toString());
}
if(connectMode == false)
{
String text = serverURLField.getText();
try
{
keySocket= new Socket(InetAddress.getByName(text),SERVERPORT);
in = new DataInputStream(keySocket.getInputStream());
out = new DataOutputStream(keySocket.getOutputStream());
pongPanel1.setText("Connected.");
pongPanel1.repaint();
out.flush();
out.writeInt(listenerUDP.getLocalPort());
pongPanel1.setText("Waiting for opponent.");
pongPanel1.repaint();
player = in.readInt();
pongPanel1.setText("You are Player"+player+".");
pongPanel1.repaint();
connectMode = true;
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}
//
// Method Name: checkChangeMode
//
// Purpose: checks if the packets just received contains
// data that would cause a change of mode
// if so acknowledge to server mode change.
// and get any additional data from server.
//
private boolean checkChangeMode()
{
boolean endGame = true;
boolean endPoint = true;
boolean startGame = true;
boolean startPoint = true;
for(int i=0; i<7; i++)
{
if(data[i] != ENDGAMECODE) endGame = false;
if(data[i] != ENDPOINTCODE) endPoint = false;
if(data[i] != STARTGAMECODE) startGame = false;
if(data[i] != STARTPOINTCODE) startPoint = false;
}
if(endGame) endGameHandler();
if(endPoint) endPointHandler();
if(startGame) startGameHandler();
if(startPoint) startPointHandler();
return endGame && endPoint && startGame && startPoint;
}
//
// Method Name: getCoords
//
// Purpose: converts packets data to coordinates for each screen object
//
private void getCoords()
{
xBall = (data[0]<<8) + (data[1] & 255); //the & 255 is since byte is
//otherwised signed.
yBall = (data[2]<<8) + (data[3] & 255);
yL = (data[4]<<8) + (data[5] & 255);
yR = (data[6]<<8) + (data[7] & 255);
}
//
// Method Name: updateScreen
//
// Purpose: used current data about object to update Pong Screen
//
private void updateScreen()
{
pongPanel1.setBallX(xBall);
pongPanel1.setBallY(yBall);
pongPanel1.setLPaddleY(yL);
pongPanel1.setRPaddleY(yR);
pongPanel1.setLScore(lScore);
pongPanel1.setRScore(rScore);
pongPanel1.setText(msg);
pongPanel1.repaint();
}
//
// Switch phase handlers called by checkChangedMode
// each handle the end of given named phase.
//
private void endGameHandler()
{
int signal;
try
{
out.writeInt(ENDGAMECODE);
signal = in.readInt();
if(signal == ENDGAMECODE)
{
whosePoint = in.readInt();
lScore = in.readInt();
rScore = in.readInt();
msg= "Player"+whosePoint+" wins!";
out.close();
in.close();
keySocket.close();
connectMode = false;
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void endPointHandler()
{
int signal;
try
{
out.writeInt(ENDPOINTCODE);
signal = in.readInt();
if(signal == ENDPOINTCODE)
{
whosePoint = in.readInt();
lScore = in.readInt();
rScore = in.readInt();
msg="Player"+whosePoint+" scores!";
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void startGameHandler()
{
int signal;
try
{
out.writeInt(STARTGAMECODE);
signal = in.readInt();
if(signal == STARTGAMECODE)
{
msg="Start Game";
lScore = 0;
rScore = 0;
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void startPointHandler()
{
int signal;
try
{
out.writeInt(STARTPOINTCODE);
signal = in.readInt();
if(signal == STARTPOINTCODE)
{
msg = "";
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
/**
* PongPanel.java
*
* Description: panel used to draw the current screen of the pong game in the
* client. At home this was a Java Bean
* @author cpollett
* @version
*/
import java.awt.*;
import javax.swing.*;
import PongClientServerDefines;
public class PongPanel extends javax.swing.JPanel
implements PongClientServerDefines
{
int lPaddleX, lPaddleY, lScore;
int rPaddleX, rPaddleY, rScore;
int ballX, ballY;
String text;
public PongPanel()
{
setBackground(Color.black);
lPaddleX = LPADDLEX;
lPaddleY = PADDLEY;
lScore=0;
rPaddleX = RPADDLEX;
rPaddleY = PADDLEY;
rScore=0;
ballX = BALLX;
ballY = BALLY;
setText("PongClient");
}
public void setText(String t)
{
text = t;
}
public String getText()
{
return text;
}
public void setLScore(int lS)
{
lScore = lS;
}
public int getLScore()
{
return lScore;
}
public void setRScore(int rS)
{
rScore = rS;
}
public int getRScore()
{
return rScore;
}
public void setLPaddleX(int x)
{
lPaddleX=x;
}
public int getLPaddleX()
{
return lPaddleX;
}
public void setLPaddleY(int y)
{
lPaddleY=y;
}
public int getLPaddleY()
{
return lPaddleY;
}
public void setRPaddleX(int x)
{
rPaddleX=x;
}
public int getRPaddleX()
{
return rPaddleX;
}
public void setRPaddleY(int y)
{
rPaddleY=y;
}
public int getRPaddleY()
{
return rPaddleY;
}
public void setBallX(int x)
{
ballX=x;
}
public int getBallX()
{
return ballX;
}
public void setBallY(int y)
{
ballY=y;
}
public int getBallY()
{
return ballY;
}
public void paintComponent( Graphics g)
{
int spacing = PREFERRED_HEIGHT/10, dash = 3*spacing/4;
int center = (PREFERRED_WIDTH-PADDLE_WIDTH)/2;
super.paintComponent(g);
g.setColor(Color.white);
g.setFont(new Font("Monospaced", Font.PLAIN, 24));
g.drawString(""+lScore, LSCORE_X, SCORE_Y);
g.drawString(""+rScore, RSCORE_X, SCORE_Y);
g.drawString(text, TEXT_X, TEXT_Y);
g.fillRect(lPaddleX,lPaddleY, PADDLE_WIDTH, PADDLE_HEIGHT);
g.fillRect(rPaddleX,rPaddleY, PADDLE_WIDTH, PADDLE_HEIGHT);
g.fillOval(ballX, ballY, BALL_RADIUS, BALL_RADIUS);
for( int i=0; i< 10;i++)
{
g.fillRect(center, i*spacing, PADDLE_WIDTH,dash);
}
}
public Dimension getPreferredSize()
{
return new Dimension(PREFERRED_WIDTH, PREFERRED_HEIGHT);
}
public Dimension getMinimumSize()
{
return getPreferredSize();
}
}
/* @(#)PongPanel.java */
|