|
Color Belot Client Code, Part I The client code for the Color Belot game consists of three files: Network.java, Network.html, and BelotConstants.java. The goal of today's lesson is to go through about half of the client code and understand it. In tomorrow's lesson, we will finish the client code. BelotConstants.java The "BelotConstants" interface has remained pretty much unchanged. Take a look at it to see what constants are being used. Network.html Since the client is an applet, an "html" file is needed to specify things such as the height and width of the applet. This file is unchanged from the previous implementation of Color Belot. Would you like to review the meaning of the applet tags?. Network.java This file has undergone significant revisions from the previous implementation of Color Belot. Since a server is now coordinating two clients, some of the information that the GUI could previously directly manipulate, must now be manipulated through a socket that connects the client to a server. For the rest of today, we will examine the "Network" class that appears in this file. Make sure that you understand the code fairly well before moving on to tomorrow's lesson! The "init" method is the first method that appears in the "Network" class. Many class variables such as "myRawPoints", and "yourRawPoints" have been added to the "Network" class and now get initialized in the "init" method. These class variables have been added because they represent information that must be displayed on the interface. Previously, the values could be directly accessed by calling methods that now exist in the server. Since client/server communication is not immediate, it is better to not have to request too much information from the server when the screen needs to be repainted. By keeping track of changes as they occur, the player interacting with the client should see a more "transparent" server. Another change to the "init" method can be seen in the first doubly nested "for" loop. There is a variable called "cardImages" that contains 29 images. The first 28 slots hold images of the 28 cards in the deck of Belot cards, the 29th slot holds the picture of the back of a card. The client must have access to all of these images, but the server will instruct the client which images need to be displayed and where the images should be displayed. The eight slot array "cardImageIndices" indicates which image is the player's first card (displayed on the far left of row 2), which image is the player's second card (displayed on the right of the first card on row 2), etc. Do you need a review of "Image"s? Notice that there are three new "Button"s in the client. In addition to "join", and "rules", there is an "againButton" that a player presses to start a new game of Color Belot once the previous game ends, a "quitButton" that a player presses to stop playing Color Belot once the game ends, and a "sendButton" that enables a player to transmit messages to his or her opponent. Do you need a review of "Button"s? Two new "TextField"s have also been added. The "incomingField" displays messages that a player's opponent has sent to him. The "outgoingField" is where the player can send messages to his opponent. Do you need a review of "TextField"s? The rest of the "init" method is the same as before. The "makeButton" method is also unchanged. That brings us to the "paint" method. The "paint" method displays the same information that it did previously. Recall that "cardOne" is the card that the player plays, "cardTwo" is the card that the opponent plays, and "cardThree" is the card that is flipped up. If anything, the "paint" method is now a little simpler, because instead of needing to make method calls to get information (such as "myRawPoints"), local class variables contain that information instead to reduce server/client traffic. The "inImage" method is passed the "x" and "y" coordinates of a mouse click and the "imageNumber" (a number between 0 and 7 representing one of the 8 locations where a clickable card image can be) that is being checked. The method returns true if the "x" and "y" coordinates are inside the appropriate image. The "legalPlay" method returns true or false based on whether the player has played a legal card. If the player plays first, any card is legal to lead. If the player plays second, the player must follow suit if possible. Since the "cardImages" array is set up such that clubs are stored in the first 7 positions, diamonds in the next 7, hearts in the next 7, and spades in the final 7, the "else if" test can immediately test to see whether the suit of the card played second matches the suit of the card played first. (Do you understand why this test works?) If the suits match, the play is legal. Otherwise, all of the player's remaining cards must be looked at to ensure that none of them match the suit of the card led. The "mousePressed" method checks to see which card has been selected and whether that card is a valid card to play. If it is valid, the "cardOne" image is set to the card selected. If the player is leading, "cardTwo" is set to the back of a card image (the opponent has not played a card yet) and a message is sent to the server via a "sendMessage" call. If the player is following, a different message is sent to the server via a "sendMessage" call. The "for" loop updates the cards that the player has left in his hand to play. Finally, a few bookkeeping things are done such as subtracting one from the "cardsToDisplay" variable which represents the cards left in the player's hand. The "itemStateChanged" method handles the user choosing an option in a "Choice" variable (i.e. a pull-down menu). One "Choice" menu allows the user to either "Accept Trump" (the suit of the flipped card after five cards are dealt) or "Dont Accept". The other "Choice" menu allows the user to call anything he wants trump (e.g. "Clubs") or to "Pass". Look at the logic of each of these choices and try to understand what is going on. In all cases, the client must communicate what happened to the server via a "sendMessage" call so that the other client can be notified of what to do. Notice if the player chooses the "Pass" option that different things get done depending on whether the player bids first (in this case, the other client still gets to bid) or second (in this case, the hand is passed out and a new hand must be dealt). Do you need a review of "Choice"s?
The purpose of the next several methods are to display "String"s, "Image"s, and other GUI components in the correct locations. These methods include "setMessages", "placeComponent", "placeComponent", "displayString", "displayStringTop", "displayStrings", "displayStrings", "displayStringsTop", and "displayCard". Finally, we get to the various class variable declarations. Notice that many of the class variables are now declared to be "protected" instead of "private". This is so that the "ClientListener" class (which will be described tomorrow) can access these variables when appropriate messages from the server are received. Note: I could have provided writer methods and left them all private. This would have been better from an OOP standpoint, but I was lazy. Sorry! |