CS 124, Spring 2017
Lab 5: Arrays

In this lab, you will work with arrays for the first time. And you will learn about animation and will use arrays to keep track of multiple animated objects in an animation.

You will need copies of ArrayStats.java and of Animation.java, which you can find in /classes/cs124. (You do not need TextIO.java for this lab.)

This lab is due by 3:00 PM next Friday, October 6. MODIFIED TO: This lab and Lab 6 will be due together by 3:00 PM on Friday, October 13. You will submit two files, named ArrayStats.java, and Animation.java, plus a file from Lab 6. Turn them in using the Submit web page, as usual.

Getting Started With Arrays

The first part of the lab is a short program that will do some work with an array of integers. For this part of the lab, you should edit the file ArrayStats.java.

The file already defines a large array of ints named numList. The values in the array lie in the range 1 to 100, inclusive. They were randomly generated using Java's Math.random() function.

Your program should compute and print the sum of all the numbers in the array and the average of the numbers. We did examples like this one in class. You should expect the average to be somewhere close to 50.5, but not exactly.

Then, for each integer in the range 1 to 100, your program should count the number of times that that integer occurs in the array. (Use nested for loops.) This part of the program should output 100 lines. Each line should contain one of the integers and the number of times that the integer occurs. The numbers should be in neat columns, with a label at the top of each column, similar to this:

               Number  How Many Times in Array
               ------  -----------------------
                  1       18
                  2       13
                  3       14
                  4       13
                  5        8
                  6       11
                  7       11
                  8       14
                  9       13
                 10       13
                 11       13

and so on. (The numbers in this table are in fact the correct values.)

You are also responsible for adding comments to the program!

Arrays, Animation, and Global State Variables

When you compile and run the program Animation.java, you will see a simple animation. The only animated object is a "moon" that continually rises and sets. But there is also a background of small white "stars". You will give the stars colors. Then you will make the stars move. And finally, you will add some other feature to the animation.

A computer animation is simply a sequence of drawings, shown rapidly one after the other, with small changes from one drawing to the next. Each drawing is called a "frame" of the animation. This is not so different from previous graphics programs that you have worked on, where the picture was drawn every five seconds. Now, however the picture is redrawn forty times per second. Another difference is that the individual frames are not independent—you have to keep track of certain information between frames, that is, between calls to the paintComponent() method.

In Java, you can have variables that are outside any subroutine definition (but still inside some class). Such variables are called global variables. A global variable keeps its value between calls to subroutines, so it can keep track of the "state" of the program as it changes over time, between calls to subroutines. For the animation program, the state includes a frameNumber that starts at 0 and goes up by one each time the paintComponent() method is called. You can animate an object by using the value of frameNumber when computing the position or other property of the object. That's what's done for the "moon" in Animation.java.

There are also two arrays in the program that are used as global state variables. The arrays store the positions of the "stars". There are 100 stars. There are two arrays, named starX and starY, each one holding 100 real numbers. The center of star number i has coordinates (starX[i],starY[i]). The arrays are created and filled with random values in a subroutine named init(). The main routine calls init() just once, at the start of the program, so the code in init() is only executed just once, and that is done before any call to paintComponent(). The init() subroutine is provided as a place where you can initialize global state variables. The two arrays are used in paintComponent() when drawing the stars.

Your first task is to give color to the stars. The stars should be randomly colored. The color will not change over time, so the color values have to be saved between frames in an array that is a global state variable. The array will hold values of type Color, so the type for the array is Color[]. You should declare the variable by adding the line

Color[] starColor;

outside any subroutine (just like the arrays starX and starY. Then you should add code to the subroutine named init(). The code should create the array and fill it with random colors. (Bright HSV colors like those used in Lab 4 would be nice.)

Finally, you should use the color values from the starColor array to set the color used for each star when that star is drawn in paintCompnent(). Now, when you run the program, all the stars should have different colors.

Your second task is to make the stars move. To get an interesting effect, in each frame, you should add a small, random amount to the x-coordinate of each star, and add a different small, random amount to the y-coordinate of each star. The random amount can be selected as a random real number in the range -1.5 to 1.5. You need both positive and negative amounts so that the stars won't drift off in one direction. Instead, they will sort of wiggle in place. (This is an example of something called Brownian motion.) Remember that the coordinates are stored in the two arrays, which are of type double[]. You just need to go through the arrays and add a random value to each element. This has to be done each time paintComponent() is called. Run the program, and see what it looks like.

Your third task is to add at least one more array to the program, and use any arrays that you add in the animation. The arrays need to be declared as global state variables. They need to be created and filled with initial values in the init() method. And they need to be updated and used in the paintComponent() method.

One simple option would be to make the stars grow and shrink as well as wiggle around. Another option would be to add a new kind of animated object. For example, you could have "falling stars" that drop from the top of the picture to the bottom of the picture. Use two arrays for their x- and y-coordinates. You could also use a third array to hold a different speed for each falling star. In each frame, just add the star's speed to the star's y-coordinate to make it move down a bit. Ideally, when a star moves off the bottom of the picture, you should move it back to the top (with a new random x-coordinate and maybe a new random speed). Instead of stars, you could make "meteors" that move diagonally or snow that falls slowly, with some brownian motion in the horizontal direction. Or you could have clouds that drift horizontally. Or you could add a house to the scene and have puffs of smoke drifting up from a chimney and getting bigger as they rise.

For full credit, you should also add some other kind of animation to the scene. If you want, you can add other individual objects, but other options are possible. Position is not the only thing that can be animated. You can animate size, so you could have trees that grow. You can animate color by varying the red, green, or blue components of the color. For example, you could change the sky color over time as a "sun" rises and sets. Animating the alpha value of a color can make something fade away over time. (You can remove the moon or leave it there. It's there mostly so that you would see some animation when you run the original program.)