Object-Oriented Space Physics: Part 2

In this assignment, we'll extend Part 1 to add a spaceship, represented by a new class, Spaceship. Since a spaceship is just one more body in our system, Spaceship will be a subclass of the Body class we already developed.

After the project is complete, the program will draw the solar system with a spaceship (in place of Comet Encke before). The program will accept keyboard controls:

Step 1: Setup

To begin, first download the starter code linked below, which includes implementations of the SolarSystem and Spaceship classes. Then add a new class with your implementation of the Body class from Part 1.

ACM API     Swing API
SolarSystem.java SolarSystem.java
Spaceship.java Spaceship.java

After these changes, you should find that the program compiles and executes, and the program should draw the solar system with a single spaceship (where Comet Encke was before). The only keyboard control that will have any effect is the space key.

All of your following work for this assignment should be with modifying the Spaceship class. (There is one exception in Step 4, where this assignment handout provides code for you to insert into Body.)

Step 2: Enabling the rockets

The next step is to complete the getThrust and setThrust methods. After you have these working, you should find that when you press the Up key, the spaceship is drawn with red rocket flares behind it — though the rocket doesn't actually have any effect on the spaceship's movement yet.

double getThrust()

Returns the force being applied by the rockets. (The default is 0, but setThrust can change the force; the method should return the last value that was given to setThrust.) This method is used by Spaceship's paint method.

void setThrust(double force)

Alters the force being applied by this ship's rockets. This method is invoked whenever the user presses or releases the up-arrow key.

Step 3: Enabling steering

We'll now turn to enabling the rocket to turn. This involves writing two methods and overriding one.

double getFacing()

Returns the direction in which this spaceship is facing. Note that because space is frictionless, the direction the spaceship is facing has nothing to do with which direction it is actually moving. This method is used by Spaceship's paint method.

void setRotation(double radiansPerStep)

Configures how many radians this ship will rotate with each step of the simulation. This method is invoked whenever the user presses or releases the left- or right-arrow keys.

Additionally, you will want to override the step method from Body. In Body's step method (which is invoked in SolarSystem for each animation frame), the body's position is updated based on its current velocity. The Spaceship's step method should still update the position, which it can do by explicitly invoking Body's step method using super.step. But it should also update the direction the rocket is facing according to the current rotational velocity as configured by setRotation.

Step 4: Propulsion

Finally, we'll modify the program so that the spaceship's rockets actually propel the spaceship. To begin, add the following method into the Body class.

public void addForce(double force, double angle) {
    // (you may need to change vx and vy to match your instance variables.)
    vx += force * Math.cos(angle);
    vy += force * Math.sin(angle);   

In Spaceship, you want to override the updateDirection method inherited from Body. The job of updateDirection, you'll recall, is to update the body's velocity based on the forces it is experiencing; SolarSystem invokes it for each animation frame. For the spaceship, the forces include not only gravitational forces but also any force resulting from the rocket flare. To compute the gravitational force, you should invoke the code you already wrote in Body, invoking it using super.updateDirection. To add in the rocket's force, you should use the addForce method that you just added into Body.