For this lab, we would like you to implement a game called Boxball. This is a simple game in which the player attempts to drop a ball into a box. Boxball has 3 levels of difficulty. With each increasing level, the box gets smaller, and the player is required to drop the ball from a greater height.
When the game begins, the playing area is displayed along with three buttons that allow the player to select a level of difficulty. Selecting a level of difficulty affects the size of the box and the position of the line indicating the minimum height from which the ball must be dropped. The player drops a ball by clicking the mouse in the region of the playing area above the minimum height line. If the ball falls completely within the box, the box is moved to a random location. Otherwise, it remains where it is. In either case, the player may go again, dropping another ball.
A running version of the program we hope you produce is provided below (if your browser handles applets correctly). Your program does not have to look exactly the same - you may choose different proportions and colors - but it should behave essentially the same way.
Click this link (while holding the Shift key) to download the Boxball starter script to your home folder.
Now open a terminal window and type
source initBoxballAs a result, there will now be a CS102/lab3 folder containing the following:
For this lab you will need to define three classes: a Box class, a Ball class, and a Boxball class that extends FrameWindowController. These will allow you to create the major components of the game, i.e., the box, the balls, and the playing area, respectively.
The Boxball class should be responsible for drawing the playing area when the program starts. It should also handle the player's mouse clicks (therefore, you know what class it should "extend", right?). If the player clicks on an easy, medium, or hard button, the starting line should move to the appropriate height. If the player clicks within the playing area above the starting line, a new ball should be created and dropped from that height.
The Box class will allow you to create and manipulate the box at the bottom of the playing area. A box is responsible for knowing how to move to a new random location when the ball lands in the box. It also is responsible for changing size if the player changes the difficulty level.
The Ball class should allow you to create a ball that falls at a constant rate. When the ball reaches the bottom of the playing area, the player should be told whether the ball landed in the box. The ball should then disappear. If the ball lands in the box, the box should move to a new location.
Start by setting the layout of your playing area, using the familiar ObjectDraw shapes. Use named constants (static final) to help you, but also be aware that you can use the methods getWidth and getHeight to get the height of the canvas if you wish. Make the playing field square. The code for building the playing area should go in the begin method of Boxball.java.
Once you have set up the playing area, add the Easy, Medium, and Hard buttons to your layout. The buttons are just filled rectangles. Use any colors you like for them, as long as the button labels are readable. When you click on a button, the location of the starting line should change. After you've displayed the three buttons, add code to the onMouseClick method that will adjust the level of the starting line, depending on the button clicked. If the player selects the "Easy" buttton, the line should be relatively low. If the player selects the "Hard" button, the line should be quite high.
Test your code now, to see if the game is laid out properly and the starting line moves in response to clicks.
Next, you should add a box to your layout. To do this, you will need to write the Box class that will allow you to create and display the box object at the bottom of the playing area.
A box looks like just a rectangle, but it has different data and methods than a FilledRectangle object does. Therefore, there is some important information you will need to pass to the Box constructor in order to construct it properly. First, you need to tell the box where it should appear on the display. Remember that its horizontal position will change over time, but its vertical position will always be the same. What are the extreme left and right values for its horizontal position?
In order for the rectangle to be drawn, you will also need to tell the box what canvas it should be drawn on. This information will be passed on to the constructor for the rectangle.
The box needs one more piece of information for it to be drawn correctly. It needs to know how wide it should be. Of course, even in its hard setting, the box should still be a little wider than the ball. Since the Boxball class will create both the ball and the box, it knows their relative sizes. It must therefore tell the box how big it should be when the box is created.
Once you have written the constructor for the Box class, you should go back to the begin method of the Boxball controller class and create a new Box.
The default setting for the game is "Easy". If the player clicks on the "Medium" (or "Hard") button, the box should get smaller (or much smaller). The box needs a method, setSize, to allow its size to change when the player clicks on Easy, Medium, or Hard. Think carefully about what parameters you need to pass to setSize to accomplish this command.
After writing the setSize method, test it by modifying the onMouseClick method in the Boxball controller. Clicking on one of the level selection buttons should now not only raise or lower the bar, but it should also adjust the size of the box.
The Ball class is different from other classes with which we have been working. Objects of this class will be active, that is, the class extends ActiveObject.
The player will create a ball by clicking with the mouse in the playing area above the starting line. When the click is detected, a new Ball should be constructed. The constructor for the Ball class should draw a ball at the appropriate location on the screen. It should also start it moving down the screen. To do so, it will call a start method, which will cause the code in run to execute.
You will notice that the skeleton of the Ball constructor we have provided for you contains the call to start. You will need to add more statements to the constructor, but you should be sure that the start method call is the last statement in your constructor.
You need to think carefully about what information a ball needs to know to construct itself properly. Recall that Boxball knows how big the ball should be (so that the ball and the box can be sized appropriately). Boxball also knows where the mouse was clicked. This should be the starting location for the ball. You need to pass this information to the Ball constructor so that it can draw itself and fall.
To get the ball to fall, you will need to do some work. This will be done in the run method. We have provided a skeletal run method for you.
We will use a bit of video game magic to make the ball appear to fall. The ball will appear to move smoothly down the screen, but in fact, it will be implemented by a series of movements; that is, the program will move the ball a short distance, wait a short time, and then move again. The run method contains a while loop to allow this. On each iteration of the while loop, the ball should move a small distance, say 10 units. Then it should wait a short time. The pause method call that we provided tells the ball to wait 50 milliseconds. There are 1000 milliseconds in a second. Moving short distances that rapidly will appear to be continuous movement to the human eye. This is the same technique that television and movies use to simulate continuous motion. To complete the while statement, you need to provide the condition that determines when to exit the while loop. The ball should stop moving when it reaches the bottom of the playing area. If you're wondering how the sample game above makes the ball appear to vanish behind the "frame" of the playing field, remember that in the objectdraw library, objects can be in front of or behind each other. A white filled rectangle will hide any object that is behind it, and there is a method sendToBack() that you can use to make sure that an object is behind all others.
Once you have written the Ball constructor and the run method, you should test them. Return to your Boxball controller class, and add code to the onMouseClick method that will construct a ball if the player clicks above the starting line in the playing area. At this point, do not worry about whether the ball falls in the box. Just check that it is drawn at the right starting location and that it makes its way to the bottom of the playing area.
Now you are ready to determine whether the ball fell in the box. As the ball reaches the bottom of the playing area, it should compare its location to the box's location. Of course, the ball will need to find out the box's location. The Box class needs to provide methods getLeft and getRight that give the positions of the edges of the box. To call those methods, the Ball class must know about the box. Go back and modify your Ball constructor to pass in the Box as an additional parameter.
If the ball lands in the box, you should display the message "You got it in!". If the ball misses, you should display "Try again!". Since the Boxball controller is responsible for the layout of the game, it should construct a Text object that displays a greeting message. The Text object should be passed to the Ball constructor as a parameter so that the ball can change the message appropriately when it hits or misses the box.
Test the additions that take care of checking whether the ball fell in the box.
Finally, use the random number generator (i.e., RandomIntGenerator) to pick a new location for the box when the player gets the ball in the box. The box should be responsible for picking the new location and moving itself. Therefore, you will need to add a method to the Box class called moveBox. Make sure that only one random number generator is created by your program!
|Class||Constructor or method||Purpose|
| ||onMouseClick||choose easy/medium/hard, drop ball|
|Box||constructor||draw the box|
| ||setSize||change size of box|
| ||getLeft||return x coordinate of left edge|
| ||getRight||return x coordinate of right edge|
| ||moveBox||move the box to a new random position at bottom of canvas|
|Ball||constructor||draw the ball, then call start|
| ||run||move ball down while still above the bottom of canvas; at bottom, check if in box, display message, tell box to move itself|
Make sure the files Box.java, Ball.java and Boxball.java are in your-home-folder/CS102/lab4. If not, copy them there, and compile and run your program one last time in that folder to make sure that everything works properly.
To submit your files go to moodle in the CS102 course page and the Lab 4 section. There will be separate place to upload for each file. Three questions for you to answer are also provided below, which should be answered in the third activity provided in the moodle under lab 4.
Good luck and have fun!
|Style (8 pts total)|
|2 pts.||Descriptive comments|
|2 pts.||Good names|
|2 pts.||Good use of constants|
|2 pt.||Appropriate formatting|
|Design (6 pts total)|
|1 pt.||Good use of boolean expressions|
|1 pt.||Not doing more work than necessary|
|1 pt.||Using most appropriate methods|
|1 pt.||Good use of if and while statements|
|1 pt.||Good choice of parameters|
|1 pt.||Only one random number generator created|
|Correctness (6 pts total)|
|1 pt.||Drawing the game correctly at startup|
|1 pt.||Changing box size correctly|
|1 pt.||Changing line height correctly|
|1 pt.||Dropping the ball|
|1 pt.||Determining if the ball landed in the box|
|1 pt.||Moving the box after the ball lands in it|
|Three feedback questions (4 pts total)|