/******************************************************************* * Selim Mimaroglu * * CS680 * Object-Oriented Design * "Marble Applet" * * Spring 2002 * * File: ~smimarog/cs680/p3/memo.txt * *********************************************************************/ Part I - Design Decision Part II - In Depth Classes Part III - Difficulties Part IV - How to play Part V - Testing Part VI - Acknowledgment and Conclusion ===================================================================== I. Design Decision ===================================================================== I.I Introduction: For this project, I used the framework supplied in our textbook: "Object-Oriented Software Development Using Java" by Xiaoping Jia Figure 6.13(p 282) This is the framework for BouncingBall Applet. This is very wisely designed framework. Using this framework made changes easier in further steps of development. Proudly, all components in my Applet are swing components. I spent some time for learning and using these components. Main differences in my program: - Instead of Applet, I used JApplet - Instead of Canvas, I used JPanel - Instead of Button, I used JButton - Instead of Label, I used JLabel - Instead of drawing marbles by fillOval() method, I have ImageIcon instances, I painted them on screen. ImageIcon instances are constructed from GIF Files. I used Netscape 6.2.2 for viewing my Applet. Netscape fully supports what I have. Latest version of Internet Explorer doesn't support my work. Although it intends to read jar file, it doesn't display anything at the end. Also appletviewer displays my applet without any problem. For compilation, creating class files and jar file, I use ant. Compiling my work using ant: ant -buildfile MarbleProject.xml As I stated above ImageIcons have GIF images, I also put GIF files in jar file for convenience. I know that some of the browsers are able to read GIF files from jar files. I had some problems in painting ImageIcons. I will talk about it in Part III - Difficulties. I.II Design: I used the framework in the book. I have following classes Marble MarbleGround Animator DoubleBufferHandler DoubleBufferedComponent Ball PlayerBall MotionUtils VectorQuantity HiResPoint and some inner classes for handling mouse events and Button press events MotionUtils, VectorQuantity, HiResPoint classes are taken from Steve Revilak's work for Pool Applet. If I talk in terms of Fig6.13 (in the textbook): - Instead of BouncingBall3, I have Marble - Instead of BouncingBallCanvas, I have MarbleGround - also MarbleGround has Ball, PlayerBall (which is shooter) extends Ball. Jia says that, frameworks are expandable. I expanded this framework by adding two more classes (Ball and PlayerBall). BouncingBall3 applet is a self driven applet. When you start this applet, a ball starts to bounce and it doesn't stop bouncing until you dispose the applet. There is no user interaction in this applet. So it needs a run method for repainting itself. In Marble Applet I don't need run method, because it isn't self driven. In order to move the balls, user has to set a mark and click on shoot button. After pressing shoot button marbles start to move, everything is repainted. Double Buffering is handled by DoubleBufferHandler. It is possible to make double buffering in MarbleGround class with adding a few more lines. But using DoubleBufferHandler class and DoubleBufferedComponent interface make everything flexible and more meaningful. Most of the Swing components are guaranteed to not to flicker. When a JButton is pressed it is guaranteed not to flicker for example. If this JButton is drawn on Canvas instead of JPanel, we don't have that guarantee. Actually I had a small problem related to this subject. I will talk about it in Part III - Difficulties ======================================================================= Part II - In Depth Classes ======================================================================= In this part I will give detailed information about each class ===> Marble - This class extends JApplet. This class has a few JPanels on it. These panels have control buttons and labels on them. Here are the buttons: - New Game: it resets everything. When a user presses "New Game" button following happens; score of player1 and player2 are set to zero. some buttons are enabled, and some are disabled resetTable() method in MarbleGround class is invoked. - Shoot: When this button is pressed, appropriate shooter is fired. shootBall() method of MarbleGround is invoked - ClearMarks: When this button is pressed marks on the table are cleared. . clearMarks() method of MarbleGround is invoked - Left: it makes all the marbles (except shooter) to make 45 degrees angular left turn. turnLeft() of MarbleGround is invoked - Right: it makes all the marbles (except shooter) to make 45 degrees angular right turn. turnRight() of MarbleGrounf is invoked - Lag: Every game starts with default player. Lagging is optional. If you want to do lagging, you should press this button. Winner of the lagging will start first. doLagging() method of MarbleGround is invoked. When any button is pressed, relevant method in MarbleGround is called. Marble just modifies its state of buttons and leaves control to MarbleGround. Here is the JLabels I have in Marble class - player1 score: It keeps score of first player. This label modified when first player scores something. Also this label holds a GIF image. It's the image of first player's marble. - player2 score: It keeps score of second player. This label is modified when second player scores something. This label also holds a GIF image. It's the image of second player's marble. ===> MarbleGround Most of the actions take place in this class. Some of the methods are summarized below: - whoIsPlaying(): returns the playing user. This method is used for keeping score. Marble object asks for this method. - whatIsScore(): returns the relative score. How many marbles did the current player get in last shot? - setLagState(): this sets the lag state. Some of the methods behave different depending on the state of lag. For example setupBalls() methods doesn't create 13 balls in the middle if Lag State is set, because while Lagging we don't need these 13 balls. - initCanvas(): a better name for this method may be initPanel(). It sets the delay, initializes the JPanel. - setupBalls(): as the name implies it setups balls. 13 balls in the center are setup. Shooter is pink ball by default. After lagging it may change, shooter will be winner of lagging step. - update(), paint(), paintFrame(): methods do the painted related tasks. - resetTable(): clear the mark, setupBalls() - setMark(): it sets a mark on the playing ground. Anywhere inside the ground (inside and outside the circle) is legal. - shootBall(): it shots the shooter. It captures all the motions. - playShot(): is called by shootBall(). after the shooter is shot game is handled by playShot(). It repositions balls and plays the game. - checkBalls(): method is the one which, implements all the rules of marble game. After the shooter is shot and everything is repositioned. When marbles settle down this method is called. I will put some of the rules I implemented here: * if shooter shots a marble out of ring, and it stays inside ring, it continues playing. It scores as many as number of marbles outside the ring. * if shooter shots some marbles out off the ring, but it is also out of the ring, the turn switches. It doesn't score anything. * and so on... - turnLeft(): when a user starts a game, hen may start from anywhere this method implements that property. When left button is pressed Marble will call turnLeft() method. It will turn all the marbles by 45 degrees to left. - turnRight(): same as turnLeft(), it turns all the marbles to the right by 45 degrees. ===>Ball Each ball has a location, direction and velocity. It knows where it is. Every Ball object (which is marble) is composed of a GIF image. It's actually an ImageIcon. Applets are loaded from servers. I needed to specify URL of the GIF images to construct them. I used below constructor: ImageIcon(URL location) All the image files are in my smimarog/public_html/marble/ directory. I got the URL Location from Marble Applet. In the init method. I used getCodeBase() method for obtaining URL base. Then I created a new URL by using the codebase of the Applet and the name of the GIF file as follows: url = new URL( codebase, "yellowball.gif"); If a ball is inside the ring, I declared them as active. De active marbles will be erased from the playing ground. A marble returns it's location when asked. ===>PlayerBall PlayerBall extends Ball. It's a class for shooters. It has some additional methods: - setPlaying(): this method sets a shooter as currently playing one. There are two shooters (players) in my game. They don't play at the same time. While one of them is playing the other waits. - isPlaying(): if this shooter is playing returns true. The following classes are taken from Steve Revilak's pool applet: ===>VectorQuantity Magnitude and direction of a vector is packed together. It's very useful in motion handling. ===>HiResPoint java.awt.Point uses Integer for storing it's coordinates. In some place, for example in left and right turns I needed something more precise, I used this method in those situations. This class didn't help me so much, but it's better than using Integers for better precision. ===>MotionUtils It's used to handle calculations of movements. It has some static methods for calculating: - distance between two coordinates - distance between two points - direction between two coordinates - direction between two points and some other useful methods which I used in handling the motion. ================================================================== Part III - Difficulties ================================================================== I had two problems, I want to talk about them: - I started developing my Applet at home, on my PC. At the beginning I used canvas instead of JPanel. On my PC I didn't have any problem with that. At sparc machines when I run the same applet, I had flickering (when I pressed to some of the buttons). I solved the problem by switching from canvas to JPanel. Swing guarantees that, there won't be any flickering if JFC are used. In this case this was the problem. Mixing awt components and Swing compinents isn't a good idea. - One of the constructors of ImageIcon is: ImageIcon(String filename) It gets the filename of the image. When I run this program from hard disk both on PC and sparc machine, I didn't have any problem. Applet downloaded the image very fine and it worked without any problem. After I put this on the web, I saw that I got some errors related to java security manager. A brief description of the problem: Applets are treated as unsecure programs (that makes sense). When I run the applet, it tried to load the images from clients machine instead of server. Solution to this problem: I specified URL addresses of the images. Getting URL addresses weren't that easy. When I simply specified it like http://www.cs.umb.edu/~smimarog/marble/ , it didn't work. So I used getCodeBase() method for getting the URL code base, and created a new URL depending on the name of the file. I got code base from Marble (JApplet), passed it as an argument to MarbleGround, from MarbleGround passed it as an argument to Ball and PlayerBall. The framework made this passing job easier. ===================================================================== Part IV - How To Play ===================================================================== - set a mark behind shooter. There are two shooters: pinkball yellowball Your mark and shooter determines the direction and the magnitude of the shot.Direction is from the mark to shooter. Magnitude is the distance between mark and the shooter. - if shooter throws any marble out of the circle and remains inside it keeps playing, otherwise the turn switches to other shooter. - Default is starting with pink ball, without doing lagging. If you want to lag, click on lag button. Winner of the lagging will start first. - At beginning of each new game you may turn 13 balls to right and left by clicking on right or left buttons. ================================================================= Part V - Testing ================================================================= Testing of this project was easier than the previous ones. We have a user interface and we see our marbles. When something goes wrong I noticed that immediately by checking the positions of the marbles and other attributes in the game. Mainly I tested my program by playing it. What did I do when I faced errors or bugs in the program? Personally, I don't enjoy putting print statements, so I use debugger. I enjoy using jdb, it's much more better than gdb. It's possible to use it on Applets too. Here are the instructions for using jdb for Applets: compile the source code with -g option start your appletviewer in debug mode (-debug) type threads and observe threads type start type a break point play your applet, it will stop when it comes to the specified line or method. I solved my problems using debugger. =================================================================== Part VI - Acknowledgments =================================================================== I used VectorQuantity, HiResPoint, MotionUtils classes of Steve Revilak "Object-Oriented Software Design" by Xiapoing Jia Some swing tutorials from Sun.