# 9: Planetary Bodies

## Illuminations

• Free fruit and vegetables for students at Cabrillo Fresh Market in Watsonville Upper Quad on 2nd and 4th Thursdays at 11:30am

#### Ensuring Registration Priority for Next Semester (Calendar)

Higher priority registration helps you get the classes you want. To improve your registration priority:

1. Begin an education plan in WebAdvisor's Student Planning tool
2. Declare an active program/major
3. Have good academic standing

## 9.1: Reviewing Newton's Lab

### Learner Outcomes

At the end of the lesson the student will be able to:

• Describe vectors
• Work with an abstract class
• Discuss mixed mode arithmetic
• Write overloaded constructors and methods
• Prevent shadowing of variables
• Use `this()` within a constructor

### 9.1.1: Interacting Objects and Abstraction

• The book scenario is a simulation of bodies in a solar system
• Lets download and unzip the second completed scenario:

Scenario file: Newtons-Lab-2.gfar.

• Download the file to a convenient location like the Desktop
• Double-click the file to start Greenfoot and open the scenario.
• By right-clicking on the background, we can see a list of three simulations
• Before we continue, lets review some key concepts from the chapter

#### Concept Review

• Abstract class: a superclass that cannot be instantiated (`SmoothMover`)
• Constant variable: a variable that you cannot change (`Body`)
• Collection: a type of object that can hold many other objects
• Generic type: a type that needs a second type name as a parameter (`Body`)
• List: a type of collection where objects are stored in an order (`Body`)
• `null`: a special word for "no object" (see lesson 8.1.3)
• Overloading: having the same method name for two different methods or constructors (`SmoothMover`)
• `this()`: used to call one constructor from another (`Body`)

#### Reviewing the Newton's Lab Scenario

• The main types of bodies in the solar system include the sun, planets and moons
• Each of these bodies vary in size, mass, composition and velocity
• However, these bodies are similar in many ways
• Because each body has a size, mass and velocity, we can use abstraction to program a `Body` class
• The `Body` class, or its superclasses, has variables to store size, mass and velocity
• To set each characteristic, we have a parameter in the `Body` class constructor

``` public Body(int size, double mass, Vector velocity, Color color) ```

#### Abstract Classes

• The scenario uses two helper classes: `SmoothMover` and `Vector`
• `SmoothMover` is the superclass of `Body`
• If we right-click on `SmoothMover`, we notice that we cannot create an object
• Examining `SmoothMover`, we see that it has a new keyword in the header: abstract
• We declare classes abstract when we do NOT want to create objects directly from them
• Abstract classes serve only as superclasses for other classes

#### Check Yourself

1. When we simplify a set of real objects, like astronomical objects, to basic shared characteristics, like a `Body` class, we are using a process known as ________.
1. abstraction
2. an abstract class
3. characterization
4. summarization
2. True or false: we can use a parameter in a constructor to customize how an object operates.
3. True or false: An abstract class can be created by right-clicking on the class in Greenfoot.
4. True or false: All abstractions are composed in abstract classes.

### 9.1.2: Vectors

• Objects that move (for example planets) have a velocity
• Velocity is both a speed (such as 100 MPH) and a direction (such as up)
• Because of these two aspects, velocity is often represented as a vector
• A vector is a geometric object with both direction and length (magnitude)

#### Representations of Vectors • The above representation is known as polar coordinates
• Another way to represent a vector is as a pair of distances (dx, dy)
• The d in (dx, dy) stands for delta, a Greek letter used in science and engineering to mean a change
• Here is the same vector using (dx, dy): • This second image is called the Cartesian representation
• The book used a separate `Vector` class to work with vectors
• The `Vector` class is used by the `SmoothMover` class to control velocity

#### Activity: Check Yourself (3m)

1. Answer the following questions.
2. Before pressing the Record button, verify your answers with another classmate.
3. Press the Record button to submit your work.

#### Check Yourself Questions

1. A geometric object with both direction and length is called a(n) .
2. Specifying a vector using direction and length is known as the representation.
3. Specifying a vector as a pair of distances (dx, dy) is known as the representation.
4. For the vector to the right, its direction and magnitude respectively is ________, ________.
5. If a car moves 30 miles east and 40 miles north in one hour, its vector is ________

### 9.1.3: Smooth Moving and Type `double`

• The purpose of `SmoothMover` is to position and smoothly move objects on the screen
• It works by using floating-point (decimal) numbers rather than the usual integers
• For example, `SmoothMover` can have the x-coordinate `21.3`
• The important thing to notice is the decimal point
• If we move an actor along the x-coordinate in increments of `0.7` we have:
```21.3, 22.0, 22.7, 23.4, 24.1, 24.8, 25.5 ...
```
• Since a screen only allows integer numbers, we have to convert the numbers to integers:
```21, 22, 22, 23, 24, 24, 25 ...
```
• Even though the numbers are rounded down for the screen, the visual effect is smoother movement

#### Floating-Point Data Types

• Let us discuss more about floating-point numbers
• In lesson 4.4.3, we learned that Java has two general types of numbers: integers and floating-point
• Furthermore, Java has two floating-point number data types: `float` and `double`
• Type `float` uses 4 bytes of storage and type `double` uses twice as much (hence the name)
• Since type `double` uses twice as much memory it is more precise that `float`
• As with type `int`, we can declare variables of type `float` or `double`:
```double total;
float away;
```
• At this point in your programming career, you should always use type `double` for decimal numbers
• The additional memory use is small and the extra precision is usually helpful

#### Converting Numeric Types

• We can convert one number type into another using a process known as typecasting

Typecast (or just cast): convert one data type into another

• For example, the following converts a `double` into an `int`:
```double x = 12.34;
int y = (int) x;
System.out.println(x + " " + y); // prints 12.34 12
```
• The data type in parenthesis "`(int)`" changes the type of the value read from the variable that follows
• Without the `(int)` portion, the code would not compile:

Incompatible type: possible lossy conversion from double to int

• When the type changes from `double` to `int`, the decimal portion is discarded
• The `(int)` part of x is then assigned to y
• Notice that the value stored in x does not change, only the temporary x value in the expression

#### Mixed-Mode Arithmetic

• Remember from lesson 4.4.3 that different data types are stored in different forms
• An `int` is stored in 4 bytes in a binary format
• A `double` is stored in 8 bytes using a floating-point format defined by IEEE 754
• The computer needs both numbers in the same form before it can do arithmetic
• If one operand is different than the other, the compiler converts it to the wider of the two types
• For example:
`2 + 2.3`
• The first number (`2`) is an `int`
• The second number (`2.3`) is a `double`
• Java will automatically convert the `int` to a `double` (`2.0`)
• Then the computer knows how to do the arithmetic to produce a result of `4.3`
• Remember that the result of an arithmetic operation with an `int` and a `double` is always a `double`

#### Activity: Check Yourself (3m)

1. Answer the following questions.
2. Before pressing the Record button, verify your answers with another classmate.
3. Press the Record button to submit your work.

#### Check Yourself Questions

1. The difference between an integer and a floating point data type is the ability to hold a decimal .
2. : type casting permanently changes the type of a variable being cast.
3. What is the data type of the calculation for the following arithmetic expressions?
1. `1 + 2`
2. `1.2 + 3.4`
3. `1 + 2.3` ### 9.1.4: Overloading Constructors and Methods

• In the `Body` class, notice that there are two different constructors:

``` public Body() public Body(int size, double mass, Vector velocity, Color color) ```

• Notice the similarities and differences between these two signatures
• These two constructors allow us to create a new `Body` object in two different ways
• For example:

``` Body b1 = new Body(); Body b2 = new Body (50, 240.0, new Vector(270, 0.03), new Color(255, 216, 0)); ```

• When there is more than one constructor in a class, the constructor is said to be overloaded

Overloading: having the same name for two different constructors or methods.

• When constructors or methods are overloaded, they must have different parameter lists
• The first constructor has no parameters and is called a default constructor
• A default constructor sets instance variables to default values

#### Method Overloading

• We can have multiple methods with the same name as well
• The name of the method is overloaded because it refers to more than one method
• We see an example of method overloading in the `SmoothMover` class:
```public void setLocation(double x, double y)
public void setLocation(int x, int y)
```
• The names are the same but the parameters are different -- how?
• The following method calls invoke different methods:
```setLocation(1.2, 2.3); => setLocation(double, double)
setLocation(1, 2);     => setLocation(int, int)
```
• Which method gets called depends on the data types of the arguments
• We can see which method is selected by placing a different print statement inside each `setLocation()` method:
```System.out.println("setLocation(double, double)"); // one method
System.out.println("setLocation(int, int)"); // the other method
```
• Then in a `Body` constructor we call each version of `setLocation()` like:
```setLocation(1.2, 2.3);
setLocation(1, 2);
```
• When we place a body into the world, the constructor is called automatically
• Notice that calling `setLocation(double, double)` also calls `setLocation(int, int)` -- why?

#### Check Yourself

1. When two or more constructors or methods in the same class have the same name, this is known as ________.
1. overriding
2. overloading
3. overwhelming
4. not possible
2. When different constructors or methods have the same name, they must have different ________.
3. Of the following methods within a single class, ________ and ________ cannot compile together.
1. `public int foo(int a)`
2. `public int foo(int a, int b)`
3. `public int foo(double a)`
4. `public int foo(double a, double b)`
5. `public int foo(int b)`

### 9.1.5: More About `this`

• Remember from lesson 5.3.3 that the keyword `this` means this current object
• Sometimes the keyword `this` is used to avoid a problem known as shadowing

#### Shadowing

• Recall our discussion of shadowing in lesson 7.2.5
• Shadowing is when a local variable or parameter has the same name as a member variable of a class
• Local variables or parameters with same name as a member variable hide the member variable
• Hiding means that the member variable is ignored and the local variable is used
• One way to solve the hiding problem is to use the keyword `this`
• For example, look at the following constructor from `SmoothMover`:
```private Vector velocity;
// ....
public SmoothMover(Vector velocity)
{
this.velocity = velocity;
}
```
• What happens if we remove the keyword `this`?
• The problem is that `velocity` is both the name of a member variable and parameter
• We should avoid giving the same name to both member variables and parameters
• If we feel they must be the same, then we use `this` to clarify which variable is the instance variable

#### Another Use for `this`

• Recall our discussion on chaining constructors in lesson 7.4.5
• Notice the other constructor from `SmoothMover`:
```public SmoothMover()
{
this(new Vector());
}
```
• The body of the constructor has code that looks like a method call: `this(new Vector())`
• However, the code uses the keyword `this` as the name of a method
• What is happening is that `this()` calls another constructor in the same class
• Java matches the constructor based on the types of the parameters
• Note that if `this()` is used, it must be the first statement within a constructor

#### Check Yourself

1. The problem with the following code is ________.
```private int bar;
public void foo(int bar)
{
bar = bar;
}
```
2. Two ways to correct the above problem are ________ and ________.
3. In the following code, `this()` is used to ________.
```public Baz()
{
this(42);
}
```

### Exercise 9.1: Explore Newton's Lab (12m)

In this exercise, we explore the new concepts in our scenario. As we do, you will need to record all the stated questions and their answers in a text file using a text editor.

#### Specifications

1. Using a text editor, like TextPad, create a text file named `questions.txt` and copy the questions listed below into the file as you come to them. Also, record answers to all the questions in the file under the question.
2. Download the Newtons-Lab-2 scenario file, save it to a convenient location like the Desktop and unzip the file.

Scenario file: Newtons-Lab-2.gfar.

3. Double-click the `project.greenfoot` file in the unzipped folder to start Greenfoot and open the scenario.
4. Run the scenario and remember how it operates by trying out the three initializing methods:
• `sunAndPlanet()`
• `sunAndTwoPlanets()`
• `sunPlanetMoon()`
5. Locate the `SmoothMover` class and try to create a new `SmoothMover` object.

Q1: Were you able to construct an object?

6. Open the editor for the `SmoothMover` class and remove the word `abstract` from the class signature:
```public abstract class SmoothMover extends Actor
```
7. Try to compile the modified `SmoothMover` class.

Q2: Were you able to construct an object after removing the `abstract` keyword?

Q3: Why would you declare a class `abstract`?

8. Restore the `SmoothMover` class to its original condition.

Compile the class and verify there are no errors. Resolve any errors you find, getting help from a classmate or the instructor as needed.

9. Examine the code for the `SmoothMover` class and find all the overloaded constructors and methods.

Q4: Which constructors and methods were overloaded (list their names)?

For more information see lesson: 9.1.4: Overloading Constructors and Methods.

10. In the `SmoothMover` class, find the following code in the second constructor:
```this.velocity = velocity;
```

Change the code by removing the "`this.`" so it looks like:

```velocity = velocity;
```
11. Compile and run the scenario, to see how it changed.

Q5: What error did you see?

Q6: What is the method name and line number of the first error reported in the Terminal window?

Q7: Why did this error occur?

Hint: remember that `null` means "no object" and Java initializes instance variables to `null` when the variable is a reference (class) type.

12. Restore the `SmoothMover` class to its original condition.

Compile the class and verify there are no errors. Resolve any errors you find, getting help from a classmate or the instructor as needed.

13. Review your `questions.txt` file answers with another student in the class and correct any mistakes.
14. Add a comment to the top of the file that contains the name of the person with whom you reviewed the questions, like:
```Reviewed with Jane Programmer
```
15. Save the `questions.txt` file so you can submit it to Canvas as part of assignment 6.

#### Exercise Questions

1. What happens if you increase the value of the gravity constant GRAVITY?
2. What happens if you decrease the value of the gravity constant GRAVITY?
3. What happens if you change the value of the initial speed?

As time permits, be prepared to answer the Check Yourself questions in the section: 9.1.6: Review.

### 9.1.6: Review

• In this lesson we looked at the Newton's Lab Scenario
• We started by looking at vectors, which is a geometric object with both direction and length (magnitude)
• After vectors we looked at the `SmoothMover` class as a way to control movement of actors to partial pixels.
• The technique is to store the location in variables of type `double`:
```private double exactX;
private double exactY;
```
• As the actor moves, `SmoothMover` updates and stores its location in these two variables
• To position the actor, `SmoothMover` translates the floating-point numbers to integer values as needed by the display screen
```super.setLocation((int) exactX, (int) exactY);
```

Answer these questions to check your understanding. You can find more information by following the links after the question.

1. Reducing a concept or idea to the most simple or basic shared characteristics is known as ________________. (9.1.1)
2. True or false: All abstractions are composed in abstract classes. (9.1.1)
3. To make a class from which you cannot instantiate an object use the keyword _________. (9.1.1)
4. A geometric object with both direction and length is called a(n) _________. (9.1.2)
5. Specifying a vector using direction and length is known as __________ representation. (9.1.2)
6. Specifying a vector as a pair of distances (dx, dy) is known as __________ representation. (9.1.2)
7. Which of the following is a valid declaration of a floating-point variable: (9.1.3)
1. `double scoop;`
2. `float boat;`
3. `int double;`
4. `totally double;`
8. True or false: Of the two floating point types, the type you should normally use is `double`. (9.1.3)
9. When adding an `int` and a `double` together, the resulting number is of type: (9.1.3)
1. `double`
2. `int`
3. `float`
4. that depends on the number
10. When different constructors or methods have the same name they are said to be __________________. (9.1.4)
11. Within a single class, which of the following methods can exist at the same time? (9.1.4)
1. `public int foo(int a)`
2. `public int foo(int a, int b)`
3. `public int foo(double a)`
4. `public int foo(double a, double b)`
5. `public int foo(int b)`
12. Which is an example of overloading the method that follows? (9.1.4)
```public int calcValue(double number) {...}
```
1. `public double calcValue(double number) {...}`
2. `int calcValue(double num) {...}`
3. `int calcValue(double number, int value) {...}`
4. All of these
13. True or false: Shadowing is when a local variable or parameter has the same name as a member variable of a class. (9.1.5)
14. What are two ways to avoid shadowing? (9.1.5)
15. True or false: the following code calls another constructor in the same class: (9.1.5)
```public SmoothMover()
{
this(new Vector());
}
```

## 9.2: Applying Forces

### Learner Outcomes

At the end of the lesson the student will be able to:

• Write psuedocode to describe algorithms.
• Write method stubs.
• Write code to work with lists in Java.
• Write enhanced `for` loops to process items in a list.

### 9.2.1: How a Body Moves

• In this section we continue working with the Newton's Lab scenario:

Scenario file: Newtons-Lab-2.gfar.

• The class `SmoothMover` has two variables to smoothly track the position of a subclass
```private double exactX;
private double exactY;
```
• In addition, `SmoothMover` has a `Vector` that determines the amount and direction to move
```private Vector velocity;
```
• By changing the `velocity` vector, we can move smoothly -- even in a circle
• The `move()` method of `SmoothMover` updates and sets the location of the subclass
```public void move()
{
exactX = exactX + velocity.getX();
exactY = exactY + velocity.getY();
super.setLocation((int) exactX, (int) exactY);
}
```
• The `act()` method in the `Body` subclass calls the `move()` method of `SmoothMover`
```public void act()
{
applyForces();
move();
}
```
• However, before the body moves we must apply the gravitational forces of all the other bodies in space
• We need to develop code to apply the forces

#### Algorithms and Psuedocode

• When faced with a computational problem like this we develop a computer algorithm to solve it

Computer algorithm: Precise instructions for a computer to follow to accomplish a task.

• In other words, we must develop a procedure for the computer to follow in solving the problem
• A common approach is to use psuedocode to describe the solution
• We discussed psuedocode in lesson 4.2.7
• Psuedocode is an informal description of the steps for solving a problem
• Rather than worrying about details of syntax, we use a mixture of English and Java to write the solution in a code-like way
• For example, here is a psuedocode description of the solution to the problem

#### Psuedocode Description of an Algorithm to Apply Gravity

```Apply forces from other bodies:
get all other bodies in space;
for each of those bodies:
apply gravity from that body to our own;
```

#### Check Yourself

1. A list of precise instructions to accomplish a task is called a(n) ________.
2. The advantage of using psuedocode, instead of Java code, to describe an algorithm is we can omit the ________ details.
3. The line of the above psuedocode that describes a loop is ________.
4. Use psuedocode to describe the algorithm for the `move()` method.
```public void move()
{
exactX = exactX + velocity.getX();
exactY = exactY + velocity.getY();
super.setLocation((int) exactX, (int) exactY);
}
```

One possible answer

### 9.2.2: Implementing the applyForces Algorithm

• Once we have worked out the algorithm to solve the problem, we need to translate the psuedocode into computer code
• We start by writing a method stub, like:
```private void applyForces()
{

}
```
• A method stub is a syntactically correct method with few or no program statements inside the method
• We add method stubs to our code as a placeholder until we write the method body
• If a return value is required, a method stub just returns a "dummy" fixed value like `0` or `null`
• Since our particular method stub has a `void` return type, we do not need a return statement
• After adding a method stub, our code should compile
• Another thing to notice is that the method is private
• Mark a method `private` when it is not intended for use outside the class
• When a method is intended for use outside the class, mark it `public`

#### Implementing the Algorithm

• One way to implement algorithms is to write them into our code as comments like:
```//Apply forces from other bodies:
private void applyForces()
{
//get all other bodies in space;
//for each of those bodies:
//apply gravity from that body to our own;
}
```
• Then we refer to the comment as we translate the algorithm to code
• When we are finished, we can remove the comments
• Usually we only keep the comments if the algorithm is tricky

#### Finding All the Bodies

• Our first task is to get all the bodies in `Space`
• Since `Space` is a subclass of `World`, we look in the World documentation to see how to get access
• The most promising method is `getObjects()`, which returns a list of all objects in the world (or space)
```java.util.List getObjects(java.lang.Class cls)
```
• The parameter is of type `Class`, which allows us to restrict the output to a certain class of objects like `Body`
• We saw this type of parameter before in lesson 2.4.3
• To call the method, we add a ".class" to the name of the class, like:
```getObjects(Body.class)
```
• If we want all types of objects, then we use the special keyword `null` as the parameter:
```getObjects(null)
```
• Remember that `null` means "no object"
• We can only call the `getObjects()` method with a `World` object
• To obtain the `World` object, we call the getWorld() method of `Actor`:
```getWorld().getObjects(Body.class)
```
• The return type of `getObjects()` is a `List`, which implies there is a `List` type in Java
• We will look at `List` in the next section

#### Check Yourself

1. A method ________ is just enough code to allow the method to compile.
2. True or false: we add method stubs to our code as a placeholder until we write the method body.
3. The keyword `null` means no ________.
4. True or false: mark a method `private` if it should not be called outside the class.
5. Rewrite the following code in one statement rather than two:
```World w = getWorld();
List<Actor> bodies = w.getObjects(Body.class);
```

answer

### 9.2.3: Exploring Lists

• When we work with collections of items, a natural approach is to use a list
• We have used lists before when working with arrays in lesson 7.3.3
• Also, we worked with the `List` type in lesson 8.1.4
• Java has several other ways for working with lists of data including:
• ArrayList: resizable arrays
• LinkedList: nodes linked in a sequential order
• Stack: last-in-first-out (LIFO) sequence of items
• These list types shown above have a common supertype called List
• Different list types have characteristics that make them better choices in certain applications
• For example, Greenfoot has chosen a list type to keep track of actors added to a world
• We do not know, or need to know, what list type Greenfoot has chosen
• However, we need to work with the `List` type to make use of some Greenfoot features

#### List Types

• The Greenfoot feature we are interested in using is getObjects()
• Method `getObjects()` of the `World` class gets a list of all the objects in the world
• Since `getObjects()` returns a `List`, we look at the Java API for List
• When we examine the API, we see that `List` is an interface and not a class
`Interface List<E>`
• The `List` interface is a way for Java to specify a common set of methods for many different list classes
• Which underlying list class the `getObjects()` method returns is not important
• We just use the methods of the `List` interface as a common abstraction of the list classes
• The following are some commonly used methods of `List`

#### Some Commonly Used Methods of List

Method Description
add(item) Adds the specified item to the end of the list.
add(index, item) Adds the specified item at the specified index of the list.
get(index) Retrieves the item at the specified index in the list.
remove(index) Removes the item at the specified index in the list.
set(int index, item) Replaces the item at the specified index in the list.
size() Returns the number of items in the list.

#### Generic Types

• Let us look at the description of the list interface again:
`Interface List<E>`
• Notice the `<E>` after the word `List`
• This is known as a generic type
• When we use a generic type, we must include a data type inside the angle brackets: `<E>`
• The "`E`" is a place holder name and is like a parameter for the data type
• The actual type we want to store in the list is substituted for the "`E`"
• For example, if we had a list of strings we would declare a list like:
```List<String> names;
```
• Notice that the class name "`String`" replaced the "`E`" in the type name
• In our case we have a list of `Body` objects and declare a list like:
```List<Body> bodies;
```
• Since we are getting a list from the `getObjects()` method we write:

``` List<Body> bodies = getWorld().getObjects(Body.class); ```

#### Check Yourself

1. To add an item to a `List`, call the method ________.
2. To remove an item to a `List`, call the method ________.
3. To find out how many items a `List` contains, call the method ________.
4. Write an assignment statement that declares a variable `names` and calls the following method, saving the returned value in the variable.
```List<String> getNames() { /* ... */ }
```

answer

### 9.2.4: Applying Gravitational Forces

• Recall our algorithm for applying gravity:
```Apply forces from other bodies:
get all other bodies in space;
for each of those bodies:
apply gravity from that body to our own;
```
• We now have a list of all the bodies in `Space` to implement our algorithm

``` List<Body> bodies = getWorld().getObjects(Body.class); ```

• We now need to apply gravity from each body to our current body
• We do this by going through the list of bodies one by one and apply the force in turn
• If the force is from our current body, we skip applying the force
• We can step through each item in a list using a loop as shown below

#### Method `applyForces()`

```private void applyForces()
{
List<Body> bodies = getWorld().getObjects(Body.class);
for (Body body : bodies)
{
if (body != this)
{
applyGravity (body);
}
}
}
```

#### Enhanced `for` Loop

• Notice the for-loop in the above code
• The loop is the enhanced for loop we discussed in lesson 8.1.5
• Officially this loop is known as the enhanced for loop
• However, most people call this loop the for-each loop
• The for-each loop is specially designed to work with lists of data, including arrays
• It reads each item in a list and provides a variable of the list item type to work with
• Syntax:
```for (itemType variableName : listName) {
// statements to execute
}
```
• Where:
• itemType: the data type of all the list items
• variableName: the name to use for each variable
• listName: the name of the list
• Note that we do not code initialization, test and increment statements
• Instead, we declare a variable that refers to each array element
• Within the loop, we use this variable to access each array element
• For comparison we rewrite the `applyForces()` method using a standard `for` loop

#### Comparison of `applyForces()` with a Standard `for` Loop and a for-each Loop

```private void applyForces()
{
List<Body> bodies = getWorld().getObjects(Body.class);
for (int i = 0; i < bodies.size(); i++)
{
Body body = bodies.get(i);
if (body != this)
{
applyGravity (body);
}
}
}
```
```private void applyForces()
{
List<Body> bodies = getWorld().getObjects(Body.class);
for (Body body : bodies)
{
if (body != this)
{
applyGravity (body);
}
}
}
```

#### Try It: Write an Enhanced `for`-Loop (5m)

1. Download the following scenario file, save it to a convenient location like the Desktop and unzip the file.

Scenario file: Newtons-Lab-2.gfar.

2. Double-click the `project.greenfoot` file in the unzipped folder to start Greenfoot and open the scenario.
3. Open the editor for the `Space` class and add the following import statement at the top.
```import java.util.List;
```
4. Next, add a `listBodies()` method to the `Space` class:
```public void listBodies()
{
List<Body> bodies = getObjects(Body.class);
for (int i = 0; i < bodies.size(); i++)
{
Body body = bodies.get(i);
System.out.println(body);
}
}
```

When we call this method, it will list all the `Body` objects on the terminal screen.

5. Test `listBodies()` method by:
1. Right-clicking the world background and selecting one of the methods to populate the world, like `sunAndPlanet()`.
2. Right-clicking the world background and selecting the `listBodies()` method

The Terminal window should display a list of `Body` objects like:

```Body@76f16233
Body@6134825b
```
6. Change the regular `for`-loop to the enhanced `for`-loop and retest your code.
```for (Body body : bodies)
{
System.out.println(body);
}
```

Do you see any changes between the two `for`-loops?

7. Save your updated scenario as we will be adding to it in the next exercise.
8. Be prepared to answer the following Check Yourself questions when called upon.

#### Check Yourself

1. In the `applyForces()` method, `this` (shown below) refers to the ________ `Body` object.
`if (body != this)`
2. True or false: The method `applyForces()` applies gravity from every object in `Space` to the current object
3. Rewrite the following loop using an enhanced for loop:
```int[] scores = {90, 95, 87, 89, 98};
for (int i = 0; i < scores.length; i++)
{
System.out.println(scores[i]);
}
```

Example answer

4. True or false: the for-each loop typically requires less code to write.

### 9.2.5: Calculating Gravity

• We have solved the problem of accessing each object in space
• However, we still have not applied the actual gravitational force
• We apply gravity in the `applyGravity()` method
```private void applyGravity(Body other)
```

#### About Gravity

• Gravity is a force of attraction between objects with mass
• Newton's famous formula for gravity is shown in the following image from Wikipedia: • Where:
• F: the force between the masses
• G: the gravitational constant
• m1: mass of the first body
• m2: mass of the second body
• r: distance between the masses
• Every body has a mass that attracts other bodies
• The attraction is a force along the line that interesects both masses
• The force is proportional to the product of the two masses divided by the square of the distance between them
• The `applyGravity()` method implements this equation for all `Body` objects in `Space` as follows

#### Method applyGravity()

```private void applyGravity(Body other)
{
double dx = other.getExactX() - this.getExactX();
double dy = other.getExactY() - this.getExactY();
Vector dv = new Vector(dx, dy); //sets direction; length to be done
double distance = Math.sqrt(dx * dx + dy * dy);
double force = GRAVITY * this.mass * other.mass / (distance * distance);
double acceleration = force / this.mass;
dv.setLength(acceleration);
addToVelocity(dv);
}
```

#### Notes on the Code

• The first two lines calculate the x and y direction of `other` to this object
• Then the code creates a new vector using these values
• The vector has the correct direction but not the correct length (force)
• We calculate the correct length using the Pythagorean theorem:

``` a2 + b2 = c2 ```

• The image below from the textbook (p. 148, 1/e: p. 94) shows the calculation
• To calculate the square root, we use the `Math.sqrt()` method from the Java Math class
```double distance = Math.sqrt (dx * dx + dy * dy);
```
• The next line calculates the strength of the force using Newton's formula
• The last task is to calculate the acceleration given by Newton's second law of motion:
`F = ma  or  a = F / m`
• This acceleration is used to set the length of the vector force, which is added to the body

#### Distance in Relation to dx and dy #### Methods of the Java Math Class

Name Description Example Result
abs absolute value Math.abs(-3.9)
Math.abs(3.9)
3.9
3.9
log natural log Math.log(10.0) 3.20...
pow powers Math.pow(2.0, 3.0) 8.0
sqrt square root Math.sqrt(4.0) 2.0

#### Check Yourself

1. ________ is a force of attraction between objects with mass.
2. True or false: the numbers in `applyGravity()` need to be type `double` so the numbers may have fractional parts.
3. The `Math.sqrt()` method has ________ parameter(s).
4. If a planet moves 30 miles east and 40 miles north in one hour, its vector is ________
1. 30 miles per hour northeast
2. 40 miles per hour northeast
3. 50 miles per hour northeast
4. 30 miles per hour east and 40 miles per hour north

### Exercise 9.2: Experimenting with Force (10m)

In this exercise, we experiment with how changes in GRAVITY, mass and initial velocity of the bodies affect the stability of the system.

#### Specifications

1. Using a text editor, like TextPad, create a text file named `settings.txt` to record your best settings for the following:
1. GRAVITY in Body
2. Mass, direction, velocity for both bodies in the `sunAndPlanet()` method
For example, from the initial values:
```GRAVITY = 5.8
mass1 = 240.0
direction1 = 270
velocity1 = 0.03
mass2 = 4.2
direction2 = 90
velocity2 = 2.2
```
2. Start Greenfoot and open the Newton's Lab 2 scenario from the last exercise. If you did not save it, you can download it again:

Scenario file: Newtons-Lab-2.gfar.

3. Run the scenario and remember how it operates by trying out the three builtin methods:
• `sunAndPlanet()`
• `sunAndTwoPlanets()`
• `sunPlanetMoon()`
4. Change the gravity constant at the top of the `Body` class and see what happens.
```private static final double GRAVITY = 5.8;
```

Try changing GRAVITY by 1/2, doubling it, changing it by 1 and by 0.1.

5. Choose your best value for `GRAVITY` and record it in your `settings.txt` file. Then recompile and run the scenario to verify it works well.

If you have problems, ask a classmate or the instructor for help as needed.

6. Open the `Space` class and experiment with changes to the mass or initial velocity of the bodies in `sunAndPlanet()`:
```addObject(new Body (20, 4.2, new Vector(90, 2.2), ...);
//                       |               |   |
//                      mass      direction  speed
```

When experimenting you should change only one variable at a time.

Note that you may find it challenging to find a stable system. If so, you may want to read the Wikipedia article: Stability of the Solar System.

7. Choose your best values for the mass, direction and velocity (velocity) for both objects and record them in your `settings.txt` file.
8. Save a copy of your settings.txt file to submit to Canvas as part of assignment 6.

When finished, please help those around you.

### 9.2.6: Review

• In this lesson we looked at the SmoothMover class as a way to control movement of actors to partial pixels.
• The technique is to store the location in variables of type `double`:
```private double exactX;
private double exactY;
```
• As the actor moves, `SmoothMover` updates and stores its location in these two variables
• To position the actor, `SmoothMover` translates the floating-point numbers to integer values as needed by the display screen
```super.setLocation((int) exactX, (int) exactY);
```
• We then looked at how to get gravitational force from all the bodies using lists
```List<Body> bodies = getWorld().getObjects(Body.class);
```
• With access to the force of gravity we can develop a simulation of planets in space
• To develop our simulation, we used psuedocode to develop a computer algorithm

Computer algorithm: Precise instructions for a computer to follow to accomplish a task.

• As an example, we looked at the following psuedocode

#### Psuedocode Description of an Algorithm to Apply Gravity

```Apply forces from other bodies:
get all other bodies in space;
for each of those bodies:
apply gravity from that body to our own;
```
• After development, we translated the algorithm from psuedocode to Java code
• We started by writing a method stub
• The method stub allows us to compile our program as we translate the psuedocode
• After developing the stub, we put the psuedocode in comments to make the translation easier
• Our next step is to translate each statement to Java code

#### Method Stub with Psuedocode

```//Apply forces from other bodies:
private void applyForces()
{
//get all other bodies in space;
//for each of those bodies:
//apply gravity from that body to our own;
}
```
• The last step was to apply gravity using Newton's famous gravity formula • Where:
• F: the force between the masses
• G: the gravitational constant
• m1: mass of the first body
• m2: mass of the second body
• r: distance between the masses
• We applied the formula in a method named `applyForces()`

#### Check Yourself

Answer these questions to check your understanding. You can find more information by following the links after the question.

1. What is an algorithm? (9.2.1)
2. Why do people use psuedocode to describe an algorithm? (9.2.1)
3. Use psuedocode to describe the algorithm for the following method:
```public void move()
{
exactX = exactX + velocity.getX();
exactY = exactY + velocity.getY();
super.setLocation((int) exactX, (int) exactY);
}
```
4. Write a method stub for an algorithm that gets two numbers, adds them together and returns their sum. (9.2.2)
5. What is the special word that means, "no object"? (9.2.2)
6. What line or lines of code will get all the Body objects from within the Body class? (9.2.2)
7. What methods of the `List` interface add items to a list? (9.2.3)
8. What method of the `List` interface removes items from a list? (9.2.3)
9. What methods of the `List` interface finds out how many items are in a list? (9.2.3)
10. Write a statement that calls the following method and saves the returned value in the variable `names`: (9.2.3)
```List<String> getNames() { /* ... */ }
```
11. What does `this` refer to in the following method? (9.2.4)
```private void applyForces()
{
List<Body> bodies =
getWorld().getObjects(Body.class);
for (Body body : bodies)
{
if (body != this)
{
applyGravity (body);
}
}
}
```
12. Rewrite the following loop using an enhanced for loop: (9.2.4)
```int[] scores = {90, 95, 87, 89, 98};
for (int i = 0; i < scores.length; i++)
{
System.out.println(scores[i]);
}
```
13. Which loop requires less code to write: standard or enhanced `for` loop? (9.2.4)
14. ____________ is a force of attraction between objects with mass. (9.2.5)
15. Write a statement that computes the square root of `42`. (9.2.5)

## 9.3: Projectile Motion

### Learner Outcomes

At the end of the lesson the student will be able to:

• Create a projectile animation.
• Write code to detect collisions between objects.

### 9.3.1: Creating a Side-View World

• Gravity is an important effect in may scenarios
• Whenever we have creature that walk, jump, throw things or fire projectiles, we need gravity
• In this section we explore how to fire projectiles using a cannon
• The same techniques can be used for any projectile: from slingshots to monkeys throwing bananas
• Lets download and unzip the following starter scenario:

Scenario file: cannon-lesson.gfar.

• Download the file to a convenient location like the Desktop and double-click the file to start the project

#### Creating the World

• For this scenario we want a side-view world (`CannonWorld`)
• At the bottom of the world we will have a ground for actors to walk and rest upon
• We construct our ground using a simple tile image: • The image does not cover the world so we will need to place the image in multiple places
• We can place the tiles easily with a loop
• Since the tile width is 32 pixels, we space the ground tiles using the tile width
• First we code a method `setup()`, which is called from the constructor
• Then we place the following loop in the setup method

#### Loop to Place Ground Tiles

```for (int i = 0; i < 19; i++)
{
int x = i * 32 + 16;
int y = GROUND_HEIGHT + 16;
addObject(new Ground(), x, y);
}
```

#### Placing Targets

• In addition to the ground, we place a few targets on the ground
• The targets give the projectile something to aim at
• We place the targets in the world using code like the following:
```addObject(new Target(), 310, GROUND_HEIGHT - 22);
addObject(new Target(), 530, GROUND_HEIGHT - 22);
```

#### Try It: Create a Side-view World (5m)

1. Download the following scenario file, save it to a convenient location like the Desktop and double-click the file to start the project.

Scenario file: cannon-lesson.gfar

2. Open the editor for the `CannonWorld` class, add a method named `setup()` and call the `setup()` method from the constructor.
3. In the `setup()` method, add the following statements inside the constructor:
```for (int i = 0; i < 19; i++)
{
int x = i * 32 + 16;
int y = GROUND_HEIGHT + 16;
addObject(new Ground(), x, y);
}
```
4. Next, add a few targets to the world using the `addObject()` method like:
```addObject(new Target(), 310, GROUND_HEIGHT - 22);
```
5. Save your updated scenario as we will be adding to it in the next exercise.

### 9.3.2: Projectiles and Gravity

• In this section we develop the projectile to throw
• We start by making a `Cannonball` class as a subclass of `SmoothMover`
• Notice the capital "C" on cannonball
• To look professional, all class names should start with a capital letter in Java
• The `SmoothMover` superclass ensures smooth moving of our projectile

#### The Flight of the Cannonball

• Projectiles are objects which have only a gravity force acting on them
• For our example we will use a cannonball: • We track the flight of the cannonball by using a velocity vector of the `SmoothMover` superclass
```private Vector velocity;
```
• We specify gravitational force by defining a vector in `CannonWorld`
```public static final Vector GRAVITY = new Vector(0.0, 0.2);
```
• As the ball travels we apply the force of gravity in the `Cannonball` class
```addToVelocity(CannonWorld.GRAVITY);
move();
```
• Each game cycle increases the downward movement on the projectile as shown in the following diagram

#### Vector Parabola due to Gravity #### Making a Cannonball Projectile

• There are several interesting code bits to the `Cannonball` class
• First we add two constructors to the `Cannonball` class
```public Cannonball()
{
this(new Vector(-45, 6));
}

public Cannonball(Vector velocity)
{
super(velocity);
}
```
• In addition we override the `addedToWorld()` method of `Actor`
```@Override protected void addedToWorld(World world)
{
setLocation(getX(), getY());
}
```
• Overriding a superclass method allows Java to use the subclass method instead of the superclass method
• By overriding the `addedToWorld()` method, we make sure our cannonball is positioned correctly when added to the world
• Overriding the `addedToWorld()` method is necessary because `SmoothMover` is tracking the (x, y)-coordinates with `exactX` and `exactY`
• Notice that when we override a method, common practice is to add an `@Override` annotation
• Adding the annotation makes the compiler verify we actually overrode a something
• To finish the flight of the cannonball, we update the `act()` method
```public void act()
{
addToVelocity(CannonWorld.GRAVITY);
move();
}
```
• Before the cannonball moves, we apply the force of gravity
• Applying gravity makes our cannonball move like a projectile

#### Try It: Make a Projectile (4m)

1. Start Greenfoot and open the Cannon scenario from the last Try It.
2. Create a `Cannonball` class as a subclass of `SmoothMover` and using the `cannon_ball.png` image.
3. Open the editor for the `Cannonball` class and add the following constant:
```private static final int GROUND_HEIGHT = CannonWorld.GROUND_HEIGHT - 6;
```
4. in addition, add the following two constructors:
```public Cannonball()
{
this(new Vector(-45, 4));
}

public Cannonball(Vector velocity)
{
super(velocity);
}
```
5. Also, override the `addedToWorld()` method of `Actor` to set the location in `SmoothMover`
```@Override protected void addedToWorld(World world)
{
setLocation(getX(), getY());
}
```
6. Compile the scenario to ensure you added the changes correctly.
7. In the `act()` method of `Cannonball`, add the following code:
```addToVelocity(CannonWorld.GRAVITY);
move();
```
8. Again, compile the scenario to ensure you add the changes correctly.
9. Test the cannonball by adding one to the world and pressing the Run button.
10. Save your updated scenario as we will be adding to it in the next exercise.

### 9.3.3: Shooting a Cannon

• With our world established, we now add an actor to launch projectiles
• For our example we will use a cannon #### Adding a Cannon

• We add a `Cannon` class to our scenario
• Notice the capital "C" on cannon
• To look professional, all class names should start with a capital letter in Java
• In the `act()` method of the cannon, we add controls for aiming the cannon:
```if(Greenfoot.isKeyDown("up")) {
turn(-1);
}
if(Greenfoot.isKeyDown("down")) {
turn(+1);
}
if ("space".equals(Greenfoot.getKey()))
{
fire();
}
```
• Notice the test condition of the last if-statement:
```"space".equals(Greenfoot.getKey())
```
• This condition makes sure the cannon fires only once per keypress
• We then add a method stub for the `fire()` method
```private void fire()
{
// Add projectile throwing code here
}
```
• We then compile the scenario to ensure we added the changes correctly.

#### Throwing the Projectile

• In the `fire()` method we add code to throw the projectile
```Greenfoot.playSound("fire.wav");
int angle = getRotation() - 36; // adjust angle for image
Cannonball ball = new Cannonball(new Vector(angle, 9));
getWorld().addObject(ball, getX(), getY());
ball.setRotation(angle);
ball.move(42); // clear the cannon barrel
```
• Within the method we calculate the angle of the cannon
```int angle = getRotation() - 36; // adjust for image
```
• This allows us to make sure the cannonball clears the cannon barrel by:
1. setting the rotation of the cannonball
2. moving the cannonball forward enough to clear the cannon barrel
• Once we create the cannon, we add one to the world
```addObject(new Cannon(), 60, GROUND_HEIGHT - 24);
```

#### Try It: Add a Cannon (5m)

1. Start Greenfoot and open the Cannon scenario from the last Try It.
2. Add a cannon to the world using the cannon image.
3. In the `act()` method of `Cannon`, add the following code:
```if(Greenfoot.isKeyDown("left")) {
turn(-1);
}
if(Greenfoot.isKeyDown("right")) {
turn(+1);
}
```
4. In addition, add code to move the cannon left or right along the ground, no matter the rotation of the cannon.

For more information, see 2.2.5: Actor Movement Methods and 3.5.2: Using Strings to Specify Key Presses. Notice that `move()` does not work when the cannon is rotated. Thus you will need to use `setLocation()`.

5. Now add code to the `act()` method for firing the cannon.
```if ("space".equals(Greenfoot.getKey()))
{
fire();
}
```
6. Add a method stub for the `fire()` method
```private void fire()
{
// Add projectile throwing code here
}
```
7. Compile the scenario to ensure you added the changes correctly.
8. Add the projectile throwing code to the `fire()` method:
```Greenfoot.playSound("fire.wav");
int angle = getRotation() - 36; // adjust angle for image
Cannonball ball = new Cannonball(new Vector(angle, 9));
getWorld().addObject(ball, getX(), getY());
ball.setRotation(angle);
ball.move(42); // clear the cannon barrel
```
9. Again, compile the scenario to ensure you added the changes correctly.
10. Add the `Cannon` to the world in the `CannonWorld` method `setup()`
```addObject(new Cannon(), 60, GROUND_HEIGHT - 26);
```
11. Compile and run the scenario to ensure you made the changes correctly.
12. Save your updated scenario as we will be adding to it in the next exercise.

### 9.3.4: Hitting the Ground

• When our projectiles hit the ground, they just keep going
• Then the projectile reaches the bottom of the screen and just rolls to the corner
• A better strategy is to have cannonballs disappear when they hit the ground
• Also, if the cannonball goes off screen, it should disappear
• We can use the `isTouching()` and `isAtEdge()` methods to test for these conditions
• Then we can remove the cannonballs from the world
• The following code placed in the `act()` method of `Cannonball` will perform the actions we need

#### Code in `act()` for Ground Collision

```if (isTouching(Ground.class) || isAtEdge())
{
CannonWorld world = (CannonWorld) getWorld();
world.removeObject(this);
}
```

#### Try It: Add Collision Detection for Hitting the Ground (2m)

1. Start Greenfoot and open the Cannon scenario from the last Try It.
2. Open the editor for the `Cannonball` class.
3. Add the following code to the end of the `act()` method
```if (isTouching(Ground.class) || isAtEdge())
{
CannonWorld world = (CannonWorld) getWorld();
world.removeObject(this);
}
```
4. Compile the scenario to ensure you added the changes correctly.
5. Test your changes by firing the cannon such that the cannonball hits the ground.
6. Save your updated scenario as we will be adding to it in the next exercise.

### 9.3.5: Hitting Targets

• We want something to happened when our projectile hits its target
• If a cannonball hits a target, it would likely destroy the target
• We can add a method to react when a projectile hits a target

#### Method `checkHitTarget()` of `Cannonball`

```private void checkHitTarget() {
// To react to only one type (like Enemy) change Actor to that type
Actor target = getOneIntersectingObject(Target.class);
if (target != null)
{
CannonWorld world = (CannonWorld) getWorld();
world.removeObject(target);
world.removeObject(this);
return; // in case of multiple if statements
}
}
```

#### Method `getOneIntersectingObject()`

• We call the method `getOneIntersectingObject()` because it returns the actor we hit
```Actor target = getOneIntersectingObject(Target.class);
```
• In our example, the actor is a `Target` object
• By saving the `Target` object in a reference variable, we have access to its methods
• For example, we can call the actor's `getX(`) and `getY()` methods
• If we wrote a custom method, such as `hit()`, we can call the custom method as well
• Thus, `getOneIntersectingObject()` provides more options than the easier `isTouching()` and `removeTouching()` methods
• Note that `getOneIntersectingObject()` returns `null` if it is not touching another object
• This means we need to check that the target is not null before calling methods of the target object
```if (target != null)
{
// do something with target
}
```

#### When to Call `checkHitTarget()`

• We want to call `checkHitTarget()` when the projectile is flying
• However, if a cannonball is already removed from the world, then we cannot call `checkHitTarget()`
• If we call `checkHitTarget()` when the cannonball is not in the world, we get a runtime error

java.lang.IllegalStateException: Actor not in world. An attempt was made to use the actor's location while it is not in the world. Either it has not yet been inserted, or it has been removed.

• We want to call `checkHitTarget()` only if the cannonball was not removed from the world
• We can ensure this condition by using an `if-else` statement as shown below

#### Method `act()` Calling `checkHitTarget()`

```public void act()
{
addToVelocity(CannonWorld.GRAVITY);
move();
if (isTouching(Ground.class))
{
CannonWorld world = (CannonWorld) getWorld();
world.removeObject(this);
}
else // only if the cannonball is still in the world
{
checkHitTarget();
}
}
```

#### Try It: Add Collision Detection for Hitting a Target (4m)

1. Start Greenfoot and open the Cannon scenario from the last Try It.
2. Open the editor for the Cannonball class.
3. Add the following method to check for target collisions:
```private void checkHitTarget() {
Actor target = getOneIntersectingObject(Target.class);
if (target != null)
{
CannonWorld world = (CannonWorld) getWorld();
world.removeObject(target);
world.removeObject(this);
return; // in case of multiple if statements
}
}
```
4. Compile the scenario to ensure you added the changes correctly.
5. Add an `else`-clause to the end of the `if`-statement in the `act()` method
```else // only if the cannonball is still in the world
{
checkHitTarget();
}
```
6. Compile the scenario to ensure you added the changes correctly.
7. Test your changes by firing the cannon such that the cannonball hits a target.

The target should disappear.

8. Save your updated scenario as we will be adding to it in the next exercise.

### 9.3.6: Simple Explosions

• Explosions often add excitement to a game
• We will go over a simple explosion technique in case you have a game that would benefit from an explosion
• We start by adding an `Explosion` class as a subclass of `Actor` with the `explosion1.png` image
• Then we add a constructor to play the explosion sound as shown below

#### Constructor for `Explosion` Class

```public Explosion()
{
Greenfoot.playSound("explosion.wav");
}
```

#### Processing the Explosion

• Explosions dissipate over time
• We add code to the `act()` method to make the explosion fade over time
• The fading is controlled by the transparency setting of the image
• The transparency starts at 255 and diminishes every game cycle
• When the transparency gets close to zero then we remove the explosion from the world

#### Method `act()` of the Explosion Class

```public void act()
{
int alpha = getImage().getTransparency();
if (alpha > 10)
{
getImage().setTransparency(alpha - 10);
}
else
{
getWorld().removeObject(this);
}
}
```

#### Adding an Explosion in Cannonball

• Once we have an explosion, we add it to the world when the cannonball hits a target
• We update the cannonball's `checkHitTarget()` method to add the explosion as shown below

#### Updated `checkHitTarget()` Method in `Cannonball`

```private void checkHitTarget() {
Actor target = getOneIntersectingObject(Target.class);
if (target != null)
{
CannonWorld world = (CannonWorld) getWorld();
world.addObject(new Explosion(), getX(), getY());
world.removeObject(target);
world.removeObject(this);
}
}
```

#### Other Applications

• Note that the explosion technique could be applied whenever a projectile hits an object
• For example, a tomato projectile may cause a splatter when hitting an object
• A splatter would be coded similar to an explosion

#### Try It: Add an Explosion when Hitting a Target (5m)

1. Start Greenfoot and open the Cannon scenario from the last Try It.
2. Add an `Explosion` class as a subclass of `Actor` with `explosion1.png` as the image.
3. Add the following constructor to the Explosion class
```public Explosion()
{
Greenfoot.playSound("explosion.wav");
}
```
4. Compile the scenario to ensure you added the changes correctly.
5. To process the explosion, add the following code to the act() method:
```int alpha = getImage().getTransparency();
if (alpha > 10)
{
getImage().setTransparency(alpha - 10);
}
else
{
getWorld().removeObject(this);
}
```
6. Compile and then test the scenario by adding an explosion to the world.
7. To add an explosion automatically, open the editor for the `Cannonball` class.
8. In the `Cannonball` class, add the following statement to the method `checkHitTarget()`
```world.addObject(new Explosion(), target.getX(), target.getY());
```
9. Compile the scenario to verify you added the code in the correct location.
10. Test your scenario by firing the cannon and watching the pretty explosions.
11. Save your updated scenario as to submit as part of the next quest.

### Exercise 9.3: Projectiles

In this exercise, we experiment with projectile motion.

#### Specifications

1. Complete the Try It activities we explored throughout the section including:
2. Save a copy of your completed `cannon-lesson` scenario to upload to Canvas as part of the next lab.

## Wrap Up

Due Next:
Q8: Visualize this! (10/25/18)
B9: Boss Event (Canvas) (10/30/18)
Lab 9: Asteroids (10/30/18)
Q9: Gravitational Attraction (11/1/18)
• When class is over, please shut down your computer
• You may complete unfinished lesson exercises at any time before the due date.
Last Updated: October 25 2018 @17:18:22