/*MagnificentBall is a peer-to-peer Java Ball Game to play over the Internet or with in your local intranet.*/ /** *Class MagnificentBall is the GUI of the game. * *@version 1.0 * *@author Martin Carlsson * *@see javax.swing.JFrame * *Internet programmering 1 - Course */ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.net.*; public class MagnificentBall extends JFrame implements ActionListener { /*Title, hostname, width and hight of the game area*/ private String title = "MagnificentBall"; private String hostname; private static final int xMax = 333; // the game area xMax private static final int yMax = 196; // the game area yMax private static final int xFrame = 445; // the frame xMax private static final int yFrame = 330; // the frame yMax /*GameArea och TextWriter classes*/ private GameArea gA; private TextWriter textWriter; /*Opponents Internet address*/ private InetAddress toAdr; /*Ports*/ private static final int DEFAULT_PORT = 2000; private int remotePort; private int localPort; /*Mode variables*/ private boolean hardMode = false; private JRadioButton mode; /*Labels for player 1*/ private JLabel playerOnePointStatus = new JLabel(" 0"); private JLabel playerOneLifeStatus = new JLabel(" 10"); /*Texts for player 1*/ private JLabel playerOneLifeText = new JLabel(" Life ", JLabel.CENTER); private JLabel playerOnePointText = new JLabel(" Points "); /*Labels for player 2*/ private JLabel playerTwoPointStatus = new JLabel(" 0"); private JLabel playerTwoLifeStatus = new JLabel(" 10", JLabel.CENTER); /*Texts for player 2*/ private static JLabel playerTwoLifeText = new JLabel(" Life ", JLabel.CENTER); private static JLabel playerTwoPointText = new JLabel(" Points "); /*Label for player 1 and player 2*/ private static JLabel localPortText = new JLabel("Local Port ", JLabel.LEFT); private static JLabel remotePortText = new JLabel("Remote Port ", JLabel.LEFT); private static JLabel remoteAdrText = new JLabel("Host", JLabel.LEFT); /*Four panels*/ private JPanel northPan = new JPanel(); private JPanel southPan = new JPanel(); private JPanel westPan = new JPanel(); private JPanel eastPan = new JPanel(); /*Panels within the east panel*/ private JPanel eastBottomPan = new JPanel(); private JPanel eastTopPan = new JPanel(); /*Panels within the west panel*/ private JPanel westTopPan = new JPanel(); private JPanel westBottomPan = new JPanel(); /*Panels within the south panel*/ private JPanel southLeftPan = new JPanel(); private JPanel southMiddleLeftPan = new JPanel(); private JPanel southMiddleRightPan = new JPanel(); private JPanel southRightPan = new JPanel(); /*Connect button*/ private JButton connect = new JButton("Connect"); /*övriga knappar kopplade till lyssnare*/ private JButton[] jB = new JButton[5]; private String[] jBtext = {"New Game","Paus","Continue","Quit","Help"}; /*Address and port field*/ private JTextField remoteAdrField; private JTextField localPortField = new JTextField("2000",1); private JTextField remotePortField = new JTextField("2000",1); /*Choise when disconnecting*/ private String[]options = {"Disconnect","Quit Game","Cancel"}; /*Text when host is unknown*/ private String unKnownHostText = "Check your host address and/or "+ "Internet connection!"; /*text when ports are chosen outside the allowed port range*/ private String numberFormatText = "Not a valid port number.\n"+ "Please enter a number\n"+ "between 0 and 65535!"; /*Text when incorrect ports are chosen in test mode, i.e. when playing on localhost*/ private String localHostText = "Remote and local port\n"+ "can not be the same when\n"+ "connected to your local host!"; /*Help text*/ private String helpText = " START GAME\n" + "Enter hostname and port numbers \n" + "(or use default portnumbers),\n" + "and press \"Connect\".\n\n" + "If the title bar displays Active Mode,\n" + "press\"New Game\".\n\n" + "If the title bar displays Passive Mode,\n" + "just wait.\n\n"+ " HOW TO PLAY\n"+ "Use up- and down- arrows for\n"+ "for movement. You improve your\n"+ "score by hitting the ball. If you \n"+ "miss, you lose lives, and the ball speed\n"+ "increases.(Ball speed will also increase\n"+ "with a constant rate over time).\n"+ "Game over when you or your opponent\n"+ "have no lives left.\n\n"+ "Created by Martin Carlsson"; /** *Constructs the GUI * with the parameters hostname och port. *@param hostname Name of the host to connect to *@param port Port to listen and connect to */ public MagnificentBall(String hostname, int port) { this.hostname = hostname; /*Creates address fields and adds this class as listener*/ remoteAdrField = new JTextField(hostname,10); remoteAdrField.addMouseListener(mL); remoteAdrField.addActionListener(this); /*Adds this class as listener for the port fields and the connect button*/ remotePort = localPort = port; remotePortField.setText(port+""); localPortField.setText(port+""); remotePortField.addActionListener(this); localPortField.addActionListener(this); connect.addActionListener(this); /*Radio button for choise of mode, this class added as listener*/ mode = new JRadioButton(" Hard ", hardMode); mode.addActionListener(this); mode.setBackground(Color.blue); mode.setFont(new Font("SansSerif", Font.BOLD, 14)); /*Background color for the panels*/ northPan.setBackground(Color.blue); southPan.setBackground(Color.blue); westPan.setBackground(Color.blue); eastPan.setBackground(Color.blue); eastTopPan.setBackground(Color.blue); eastBottomPan.setBackground(Color.blue); westTopPan.setBackground(Color.blue); westBottomPan.setBackground(Color.blue); southMiddleLeftPan.setBackground(Color.blue); southLeftPan.setBackground(Color.blue); southMiddleRightPan.setBackground(Color.blue); southRightPan.setBackground(Color.blue); southPan.setBackground(Color.blue); /*Layouts for the panels*/ eastPan.setLayout(new GridLayout(2, 1)); westPan.setLayout(new GridLayout(2, 1)); eastTopPan.setLayout(new BoxLayout(eastTopPan, BoxLayout.Y_AXIS)); eastBottomPan.setLayout(new BoxLayout(eastBottomPan, BoxLayout.Y_AXIS)); westTopPan.setLayout(new BoxLayout(westTopPan, BoxLayout.Y_AXIS)); westBottomPan.setLayout(new BoxLayout(westBottomPan, BoxLayout.Y_AXIS)); southLeftPan.setLayout(new GridLayout(2, 1)); southMiddleLeftPan.setLayout(new GridLayout(2, 1)); southMiddleRightPan.setLayout(new GridLayout(2, 1)); southRightPan.setLayout(new GridLayout(2, 1)); southPan.setLayout(new FlowLayout(FlowLayout.LEFT)); /*Adds subpanels to the west and panels*/ westPan.add(westTopPan); westPan.add(westBottomPan); eastPan.add(eastTopPan); eastPan.add(eastBottomPan); /* Adds the score and score text for player 1, i.e. the left player*/ westTopPan.add(playerOnePointText); westTopPan.add(playerOnePointStatus); /*Adds life status and life status text for player 1*/ westBottomPan.add(playerOneLifeText); westBottomPan.add(playerOneLifeStatus); /*Adds score and score text for player 2*/ eastTopPan.add(playerTwoPointText); eastTopPan.add(playerTwoPointStatus); /*Adds life status and life status text for player 2*/ eastBottomPan.add(playerTwoLifeText); eastBottomPan.add(playerTwoLifeStatus); /*Adds labels and text field for the address field, port field and the connect button*/ southLeftPan.add(remoteAdrText); southLeftPan.add(remoteAdrField); southMiddleLeftPan.add(remotePortText); southMiddleLeftPan.add(remotePortField); southMiddleRightPan.add(localPortText); southMiddleRightPan.add(localPortField); southRightPan.add(mode); southRightPan.add(connect); southPan.add(southLeftPan); southPan.add(southMiddleLeftPan); southPan.add(southMiddleRightPan); southPan.add(southRightPan); /*Fonts for the different labels*/ remoteAdrText.setFont(new Font("SansSerif", Font.BOLD,14)); remotePortText.setFont(new Font("SansSerif", Font.BOLD,14)); localPortText.setFont(new Font("SansSerif", Font.BOLD,14)); playerTwoLifeText.setFont(new Font("SansSerif", Font.BOLD,14)); playerOneLifeText.setFont(new Font("SansSerif", Font.BOLD,14)); playerOnePointStatus.setFont(new Font("SansSerif", Font.BOLD,14)); playerTwoPointStatus.setFont(new Font("SansSerif", Font.BOLD,14)); playerOnePointText.setFont(new Font("SansSerif", Font.BOLD,14)); playerOneLifeStatus.setFont(new Font("SansSerif", Font.BOLD,14)); playerTwoLifeStatus.setFont(new Font("SansSerif", Font.BOLD,14)); playerTwoPointText.setFont(new Font("SansSerif", Font.BOLD,14)); /*Background color for the labels*/ playerOnePointText.setBackground(Color.blue); playerOneLifeText.setBackground(Color.blue); playerTwoPointText.setForeground(Color.blue); playerTwoLifeText.setBackground(Color.blue); localPortText.setBackground(Color.blue); remotePortText.setBackground(Color.blue); remoteAdrText.setBackground(Color.blue); /*Text is set on the buttons and the buttons are added to the north panel*/ for(int i = 0; i < jB.length; i++){ jB[i] = new JButton(); jB[i].setText(jBtext[i]); jB[i].addActionListener(this); northPan.add(jB[i]); } /*Container to put everything in*/ Container con = getContentPane(); /*Adds the 4 main panels*/ con.add(northPan,BorderLayout.NORTH); con.add(southPan,BorderLayout.SOUTH); con.add(westPan,BorderLayout.WEST); con.add(eastPan,BorderLayout.EAST); /*TextWriter- and GameArea-instances are created*/ textWriter = new TextWriter(this); gA = new GameArea(this); /*The middle area(game area) is added*/ con.add(gA,BorderLayout.CENTER); /*Window listener added, size for the frame and game area is set*/ addWindowListener(windowClosing); setSize(xFrame, yFrame); gA.setSize(xMax, yMax); show(); } /** *RemoteAdrField is set to s if the host name is not set *@param s String to add to the address field */ public void setRemoteAdrFieldText(String s) { if(hostname.equals("")) remoteAdrField.setText(remoteAdrField.getText() + s); } /** *Decides what will happend when a button is pressed by calling methods in class GameArea *@param aE event triggered by a user action *@see GameArea */ public void actionPerformed(ActionEvent aE) { gA.requestFocus(); // requests focus before each event if(aE.getSource() == jB[0] && gA.activePlayer()) { //"New Game"-button pressed gA.newGame(); // new game is created } // slut if else if(aE.getSource() == jB[1]) { // if the "Paus" button is pressed if(!gA.pausPressed() && gA.playing()&&!gA.gameOver()) { gA.stopGame(); // game stops jB[1].setEnabled(false); // "Paus"-button is disabled(not pressable) setTitle(getGameTitle() + " PAUSED "); // show paus status gA.setPausPressed(true); // info about paus status is sent to the game area } } else if(aE.getSource() == jB[2]) { // if "Continue"-button is pressed if(gA.pausPressed() && gA.playing() && !gA.gameOver()) { gA.startGame(); // game starts gA.setPausPressed(false); // info about paus is over jB[1].setEnabled(true); // "Paus"-button is enabled(pressable) setTitle(getGameTitle() + "--Connected to " + getHost() + "--Active Mode"); // show active mode status } } else if(aE.getSource() == jB[3]) // if "Quit"-button is pressed quitPressed(); else if(aE.getSource() == jB[4]) { // if "Help"-button is pressed jB[4].setEnabled(false); // disabled(unpressable) JOptionPane.showMessageDialog(eastPan,helpText, // show help text title + "--Instructions", JOptionPane.INFORMATION_MESSAGE); jB[4].setEnabled(true); // Help button is enabled again(pressable) } // slut else if else if(aE.getSource() == connect) // if "Connect"-button is pressed connectPressed(); // call to the internal method connectPressed() else if(aE.getSource() == mode) { // "Hard-mode RadioButton if(mode.isSelected()) // if selected gA.setHardMode(true); // hard mode is set to true else gA.setHardMode(false); // else set to false } else if(aE.getSource() == remoteAdrField || // if enter is pressed while the address field is focused aE.getSource() == remotePortField || // or if focus is on the first port field aE.getSource() == localPortField) // or if focus is on the second port field connectPressed(); // if so, call the internal method connectPressed } // end ActionPerformed //MouseListener for the address field(Adapter class) MouseListener mL = new MouseAdapter() { public void mouseClicked(MouseEvent mE) { if(SwingUtilities.isLeftMouseButton(mE)) { if(remoteAdrField.getText().equals("Enter hostname")) remoteAdrField.setText(""); } else if(SwingUtilities.isRightMouseButton(mE)) { if(remoteAdrField.getText().equals("Enter hostname")) remoteAdrField.setText(""); } } }; //Decides what will happend when the window is closed(Adapter class) WindowAdapter windowClosing = new WindowAdapter() { public void windowClosing(WindowEvent e) { gA.disconnect(); System.exit(0); } }; /** *Called when the "Connect"-button is pressed to *make sure the user filled in correct data */ private void connectPressed() { if(!gA.connected()) { // if not connected try { String theAdr = remoteAdrField.getText().trim(); toAdr = InetAddress.getByName(theAdr); InetAddress localHost = InetAddress.getLocalHost(); localPort = Integer.parseInt(localPortField.getText()); remotePort = Integer.parseInt(remotePortField.getText()); // host address and port number is controlled if(localPort <0 || localPort >65535 || remotePort < 0 || remotePort > 65535) { JOptionPane.showMessageDialog(eastPan, numberFormatText, "Invalid Port!", JOptionPane.ERROR_MESSAGE); } else if(toAdr.equals(localHost) && localPort == remotePort || theAdr.equals("localhost") && localPort == remotePort) { JOptionPane.showMessageDialog(eastPan, localHostText, "Bad local host settings!", JOptionPane.ERROR_MESSAGE); } else if(remoteAdrField.getText().equals("")) { JOptionPane.showMessageDialog(eastPan, "No host specified!", "Bad host settings!", JOptionPane.ERROR_MESSAGE); } else gA.connect(localPort, toAdr, remotePort, xMax, yMax); } catch(UnknownHostException une) { // catch and show unknown host exception info JOptionPane.showMessageDialog(eastPan, unKnownHostText, "Unknown Host!", JOptionPane.ERROR_MESSAGE); } catch(NumberFormatException nfe) { // catch and show invalid port info JOptionPane.showMessageDialog(eastPan,numberFormatText, "Invalid Port!", JOptionPane.ERROR_MESSAGE); } } } /** *Called when the "Quit"-button is pressed to control the user's quit-choices */ private void quitPressed() { jB[3].setEnabled(false); // "Quit"-button is disabled(not pressable) int userChoise = JOptionPane.showOptionDialog(eastPan, null, // different choices are shown "Disconnection options", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, null); if(userChoise == 0) { // if "Disconnect" is chosen gA.disconnect(); // disconnect jB[3].setEnabled(true); // enabled again(pressable) } // slut if else if(userChoise == 1) { // if "Quit" is chosen gA.disconnect(); // disconnect System.exit(0); // end application } else if(userChoise == 2) // if "Cancel" is chosen jB[3].setEnabled(true); // Quit-button is enabled again } /** *Gets the host name *@return Returns the Inetaddress host name as a string */ public String getHost() { return toAdr.getHostName(); } /** *"Connect"-button is enabled or disabled *@param b true or false */ public void setConnectButton(boolean b) { connect.setEnabled(b); } /** *"Paus"-is enabled or disabled *@param b true or false */ public void setPausButton(boolean b) { jB[1].setEnabled(b); } /** *"Continue"-button is enabled or disabled *@param b true or false */ public void setContinueButton(boolean b) { jB[2].setEnabled(b); } /** *"Hard"-button is enabled or disabled *@param b true or false */ public void setHardButton(boolean b) { mode.setEnabled(b); } /** *All buttons but "Quit" and "Help" *is enabled or disabled *@param b sant eller falskt */ public void setAllButtons(boolean b) { for(int i = 0; i < jB.length - 2; i++) jB[i].setEnabled(b); } /** *Retrieves the game title *@return game title *@see #setGameTitle(String s) */ public String getGameTitle() { return title; } /** *Sets the game title *@param s game title *@see #getGameTitle() */ public void setGameTitle(String s) { title = s; setTitle(s); } /** *Sets player 1's - i.e. the player you yourself are controlling - life status *@param s life status description **/ public void setPlayerOneLife(String s) { playerOneLifeStatus.setText(" " + s + ""); } /** *Sets player 1's - i.e. the player you yourself are controlling - score status *@param s score status description */ public void setPlayerOnePoints(String s) { playerOnePointStatus.setText(" " + s + ""); } /** *Sets player 2's - i.e. the player you yourself are controlling - life status *@param s life status description */ public void setPlayerTwoLife(String s) { playerTwoLifeStatus.setText(" " + s + ""); } /** *Sets player 2's - i.e. the player you yourself are controlling - score status *@param s score status description */ public void setPlayerTwoPoints(String s) { playerTwoPointStatus.setText(" " + s + ""); } /** *Sets different colors on both players life status texts *What color is set is dependent on if c is "reset" or "p1" or "p2" *@param c flag for color */ public void setPlayerLifeColor(String c) { if(c.equals("reset")) { playerOneLifeStatus.setForeground(Color.black); playerTwoLifeStatus.setForeground(Color.black); } else if(c.equals("p1")) playerOneLifeStatus.setForeground(Color.magenta); else if(c.equals("p2")) playerTwoLifeStatus.setForeground(Color.magenta); } // Main public static void main(String[] args) { String hostname = ""; int port = DEFAULT_PORT; String usage ="Usage:\n"+ "java MagnificentBall\n"+ "java MagnificentBall \"hostname\" \"port\""; if(args.length > 0) { System.out.println(usage + "\n\n"); hostname = args[0]; } if(args.length > 1) { try { port = Integer.parseInt(args[1]); } catch (NumberFormatException e) { System.out.println(usage); } } new MagnificentBall(hostname, port); // starts the game } } // End MagnificentBall