Rather than just setting the eye color randomly, it would be nice if at the time the Monster object is created, the main Processing object could tell the Monster what its eye color should be. In the main Processing object, the setup method is called once, at the time the window is first constructed. We need a setup method for the Monster object that is called when the Monster object is constructed. In Java, each class can define a constructor method that is called automatically when an object is created from that class. The constructor method has the same name as the class but does not have a return type listed, so unlike the setup method in the main Processing object, it won’t be preceded by void. In the case of the Monster object, the constructor needs information to construct the object. Namely, it needs the amount of red, green, and blue in the Monster’s eye color. So, the Monster constructor will need three parameters, each of which is an int. The code is shown in Figure 2.4.1.
We have a class to serve as a blueprint for a Monster for a Monster object. Attributes of a Monster object are represented by instance variables defined in the class. Stuff the object can do is represented by methods in the class. In our example, the Monster object each have an eye color attribute, which is represented by three instance variables in the class: eyeColorRed, eyeColorGreen, and eyeColorBlue. If we look at the Monster object displayed in Figure 2.4.3, though, you could certainly point out other attributes of a Monster object. For example, the position of the Monster in the window, the speed and direction with which it is moving, and the size all could be considered attributes of a Monster object.
Consider the size attribute. The size is not explicitly represented in the class with an instance variable. Rather, it is implicitly represented inside the display method. But if we want to create Monster objects with varying sizes, it would make sense to create an instance variable to represent the size of the Monster and use that instance variable in display. For example, we could create instance variables outerWidth and outerHeight to represent the size of the outer ellipse. The size of the facial features could also be instance variables, but let’s make them proportional to the width and height of the outer ellipse instead. Since we want the main Processing object to tell the Monster object what size it should be when it is first constructed, we add parameters for the initial outer width and the initial outer height to the constructor as shown in Figure 2.4.4. Figure 2.4.5 shows the code in the main Processing object that calls the constructor with five parameters now instead of three, while Figure 2.4.6 shows the results.
The position, speed, and direction are attributes of the Monster object that we are keeping track of in the main Processing object. Our program might be cleaner if we moved these into the Monster objects. For example, the code in Figure 3.7 includes two additional instance variables, currentX and currentY, that are used to keep track of the location of the Monster in the window. The display no longer takes the x-location and y-location as parameters. Instead, display draws the Monster in the location specified by the current values of currentX and currentY. These values are set initially in the constructor based on the parameters x and y. Note that I shortened the names of the outerWidthInit and outerHeightInit parameters to the constructor to get the code to fit when I converted the Processing sketch to PDF. In general, it is better to use more descriptive identifiers.
One important thing to notice about this code is that we now have instance variables (namely, teethWidth, teethHeight, eyeWidth, and eyeHeight) with initial values that are not set directly by parameters in the constructor. Instead, the values of these variables are based on the values of outerWidth and outerHeight. This makes the code in display cleaner – rather than calculating the width of the teeth and eyes each time display is called, we calculate these values in the constructor, which is run only once.