CS 161 Lab G - Bouncing Balls

Due Fri Mar 13 at the start of class

Overview

In this lab, you will modify an existing program in order to create an animation of a number of colored balls bouncing around in a box, changing properties (e.g., color, size, speed) when they hit the walls. Because there are too many balls to keep track of individually, you'll need to use an array to track them all.

This lab should be completed in pairs. You will need to find a different partner than you had for the last lab. Remember to switch off who is driving and who is navigating!

Objectives

Necessary Files

You will need to download and extract the BlueJ project from the BouncingBall.zip file. This project will supply you with the following classes that you will need to modify.

Assignment Details

In this lab, you will not need to write any new classes! However, you will need to modify the provided existing classes in order to add in extra functionality.

You can run the program by instantiating a new BallCourt object. The easiest way to do this is to right-click on the class in BlueJ.

If you run the program without modifying anything, you should see a single red ball bouncing around on the screen:

Your task is three-fold: (1) replace this singleBall with a collection of multiple balls, (2) add the ability for the balls to have a random color, and (3) have the balls change when they hit a wall.

Part 1: Multiple Balls

Your first step is to modify the BallCourt class so that the court has more than one moving ball.

  1. The first thing you shuld do is modify the BallCourt's constructor so that it takes as a parameter the number of balls to display (numBalls). You'll need to provide this value when you instantiate the BallCourt.
  2. You'll need to declare and instantiate a new array of length numBalls (the constructor's argument) to hold your collection of balls. Think: should this be an instance or a local variable?
    • Recall that you can declare a new array variable using (for example):

      DataType[] arrayName;

      and you can create a new array and assign it to that variable using:

      arrayName = new DataType[arrayLength];
    • You may notice that there are "TODO" comments scattered around the class. These will tell you where to put your code. Make sure to delete the TODO comment once you've done the task!
  3. The next thing you should do is fill your array with new Ball objects! You should use a loop to go through each spot in the array (each room in the hotel) and make a new Ball() to put in each room.
    • Recall that you can treat spots in the array as regular variables, and assign values (including new objects) to them as such. For example:
      Robot[] myArray = new Robot[10]; //an example array of Robots
      myArray[5] = new Robot(); //assigns a new Robot to room 5
    • We also tend to use for loops to fill arrays, with the length of the array as our stopping condition. For example:
      for(int i=0; i < myArray.length; i++)
      {
        myArray[i] = new Robot(); //assigns a new Robot to every room!
      }
  4. This is a good time to switch drivers.
  5. Next, modify the (bottom of the) paintComponent() method to use a loop to draw ALL of the balls on the BallCourt, rather than just the example singleBall. (Remember to stop drawing the singleBall!)
    • You'll again want to use a for loop to go through the array of Ball objects. Instead of calling getters() on the example singleBall, you'll want to call them on the ith item in your array. For example:
      myArray[i].getColor() //calls getColor() on the item in room i.
                            //do something with this value!

      Again, you can treat spots in the array as regular variables, and call methods on them as such.

      • Helpful hint: remember that you initialize Balls (create new ones) in the constructor, not in paintComponent()!
    • Remember to tell the brush to use the color of the ball, and to draw an oval for the ball in the correct spot!
    • When this is completed, you should be able to run the program and see a large number of red circles sitting on the screen.
  6. Finally, modify the (top of the) paintComponent() method to go through your array and tell each Ball in the array to take a step. Remember to stop moving the example singleBall; at this point you should just remove that variable entirely.
    • After you do this, you should be able to see all your red Balls moving and bouncing around the BallCourt! (Try testing your program using 25 balls--that's usually a pretty good number).
  7. This is a good time to switch drivers.

Part 2: Colorful Balls

This is great and all, but it will look better if we can change the color of the balls. Modify the Ball class so that each Ball is created with a random color.

  1. If you go to the Ball class, you can see that they are all given a specific color in the constructor. This color is drawn from a constant at the bottom of the class called PRETTY_COLORS that is an array of Color objects (a Color[]).
    • You can choose a random Color from this array by choosing a random number to use an as index into that array--it's like picking a random room number and going to that room to get the Color!
  2. You can use the provided Random object's nextInt() method to get a random number between 0 and the parameter. Think about what should be the lower and upper bounds of this random number. (Hint: think about the number of items in the array).
    • Remember that you can figure out how many items are in an array by using the .length attribute. For example:
      int arrayLength = myArray.length;
    • IMPORTANT: It is always better to be "general" and use the .length of an array, rather than trying to count the items and using a "hard-coded" number. After all---what happens if you decide to add more items (more colors) later? You'd have to remember where you hard-coded an item count and change that code as well! So much work...
  3. After you've selected a random index (a random room), assign whoever is in that room in the PRETTY_COLORS array to be the Ball's color.
  4. Once this works, you should be able to have lots of multi-colored balls bouncing around your BallCourt! How festive!
  5. Have you been switching drivers?

Part 3: Mutating Balls

There is one more step: in order to make things more interesting, modify the Ball class further so that each Ball changes when it bounces off of a wall. Bouncing off one wall (your choice of which) should have the Ball change Color.

  1. Inside the Ball's move() method you should see logic for bouncing off a wall. Take a moment to look over the code and make sure you understand it. Add a few inline comments to note down what is going on! (This is good practice, and will help you out later).
  2. In addition to the current functionality, add code so that the Ball changes color when it hits one wall (your choice of which). This will involve picking a new color from the PRETTY_COLORS array and assigning that to the Ball's attribute.

  3. However, rather than picking a Color randomly, you should instead make it so that the Balls change color to the next Color in the array. To do this, you'll need to keep track of the index of the current color--the colorIndex. Since you'll want to remember this across method calls, you will need to add it as an attribute of your Ball.
    • Remember to make instance variables private, to declare them at the top, and then to assign values to them in the constructor. Think: do you already have some code that picks what the initial (random) colorIndex should be?
  4. Whenever the Ball hits a wall, you'll want to increase this index by 1, and then change the Color attribute.
  5. What happens when you increase the colorIndex so that it goes past the end of the list? You should make it so that the color starts over at the beginning of the list. You can cause the index to "cycle" by using an if statement (or by clever application of the % operator).
  6. The logic of when to "cycle around" can get tricky! You need to make sure that you don't go outside of the bounds of array, but also that you start back at the beginning. Your Balls should be able to assume every color, from red to magenta.
    • Pro Tip: try testing your program by making a collection of only 1 Ball (so your Ball[] has a length of 1). This makes it easier to visually track if a single ball changes color. You can also (temporarily) give the balls a non-random color to help track what is happening.
  7. Hitting each other wall should also make some change to the Ball. For example, maybe one wall makes it larger and one wall makes it small. Or maybe one wall speeds up the Ball, and another slows it down. You are welcome to mix and match effects or come up with your own---but at least one wall needs to change the Ball's color!
    • If you've got more ideas, you could even make it so that different halves of the wall produce difference changes! How might you add in this functionality?
    • It is also possible to make different regions change the Ball--maybe the ball slows down when it nears the center of the BallCourt. Make this as interesting as you want!

Extensions

Here are some further options you might enjoy. Be sure to finish the main part of the program first!

Submitting

  1. Make sure both of your names are in the JavaDoc comment on both of the classes you modified (Ball and BallCourt). If your names aren't on your assignment, we can't give you credit!
  2. Right-click on the project folder you downloaded, then:
    • If using Linux, select Compress...
    • If using Windows, select Send to and then Zip file
    • If using Mac, select Compress ... items

    This will let you take the selected folder (or files) and generate a new compressed .zip file.

  3. Navigate to the course on Moodle (Lecture Section A), (Lecture Section B). Upload your .zip file to the Lab G Submission page. Remember to click "Save Changes"! You may submit as often as you'd like before the deadline; we will grade the most recent copy.
  4. While you're on Moodle, remember to fill out the Lab G Partner Evaluation. Both partners need to submit evaluations.

Grading

This assignment will be graded out of 20 points.