Helper classes: SmoothMover and Vector

6.2 Helper classes: SmoothMover and Vector

In this scenario, we are using two general purpose helper classes: SmoothMover and Vector . These are classes that add functionality to a given scenario, and can be used in different scenar- ios for similar purposes. (These two classes are in fact used in a number of different existing projects.)

The SmoothMover class provides smoother movement for actors by storing the actor’s coordi- nates as decimal numbers (of type double ), rather than integers. Fields of type double can store numbers with decimal fractions (such as 2.4567), and thus are more precise than integers.

For displaying the actor on screen, the coordinates will still be rounded to integers, since the location for painting on screen must always be a whole pixel. Internally, however, the location is held as a decimal number.

A SmoothMover can, for example, have the x-coordinate 12.3. If we now move this actor along the x-coordinate in increments of 0.6, its successive locations will be

6.2 Helper classes: SmoothMover and Vector

and so on. We will see the actor on screen at rounded x-coordinates. It will be painted at the fol- lowing x-coordinates

12, 13, 14, 14, 15, 15, 16, 17, 17, . . . and so on. Altogether, even though it is still rounded to integers for display, the effect is

smoother movement than dealing exclusively with int fields. The second bit of functionality that the SmoothMover adds is a movement vector. Every object

of a subclass of SmoothMover holds a vector that indicates a current direction and speed of movement. We can think of a vector as an (invisible) arrow with a given direction and length (Figure 6.4).

Figure 6.4 A SmoothMover object with a movement vector

The SmoothMover class has methods to change its movement by modifying its movement vector, and a move method that moves the actor according to its current vector.

Side note: Abstract classes If you right-click the SmoothMover class, you will notice that you cannot create objects of this

class. No constructor is shown. When we examine the source code of that class, we can see the keyword abstract in the

class header. We can declare classes as abstract to prevent creation of instances of these classes. Abstract classes serve only as superclasses for other classes, not for creating objects directly.

Exercise 6.6 Place an object of class Body into the world. By examining the object’s popup menu, find out what methods this object inherits from class SmoothMover. Write them down.

Exercise 6.7 Which of the method names appears twice? How do the two versions differ?

82 | Chapter 6 ■ Interacting objects: Newton’s Lab

Concept: Terminology: Overloading Overloading is the use of the same

It is perfectly legal in Java to have two methods that have the same name, as long as their method name

parameter lists are different. This is called overloading. (The name of the method is for two different

overloaded—it refers to more than one method.) methods or constructors.

When we call an overloaded method, the runtime system figures out which of the two methods we mean by examining the parameters we supply.

We also say that the two methods have different signatures.

The second helper class, Vector, implements the vector itself, and is used by the SmoothMover class. Note that Vector is not listed in the Actor group of classes. It is not an actor—it will never appear in the world on its own. Objects of this class are only ever created and used by other actor objects.

Vectors can be represented in two different ways: either as a pair of distances in their x and y coordinates (dx, dy) or as a pair of values specifying the direction and its length (direction, length). The direction is usually specified as the angle from the horizontal.

Figure 6.5 shows the same vector with both possible specifications. We see that either the (dx, dy) pair or the (direction, length) pair can describe the same vector.

Figure 6.5 Two possible ways to specify a vector

The first representation, using the x and y offsets, is called a Cartesian representation. The second, using the direction and length, is a polar representation. You will see these two names used in the source code of the Vector class.

For our purposes, sometimes the Cartesian representation is easier to use, and sometimes the polar representation is easier. Therefore, our vector class is written in a way that it can deal with both. It will do the necessary conversions internally automatically.

Exercise 6.8 Familiarize yourself with the methods of the SmoothMover and Vector classes by opening the editor, and studying their definition in Documentation view. (Remember: you can switch to Documentation view using the menu in the top right corner of the editor.) You can also read the source code, if you like, but this is not strictly necessary at this stage.

Exercise 6.9 Place a Body object into the world. Which of the methods inherited from SmoothMover can you call interactively (through the object’s menu)? Which can you not call at this stage?

6.3 The existing Body class