The Ship Class

The Ship class is responsible for updating the ship's position, keeping it within the bounds of the game field and keeping track of the state it is in. It can either be alive or exploding. In both cases we keep track of the amount of time the ship has been in that state. This state time can then be later used to do animations, for example, just as we did it in Super Jumper and its WorldRenderer class. The ship will get its current velocity from the outside based on the user input, either accelerometer readings as we did it for Bob, or based on a constant depending on what on-screen buttons are being pressed. Additionally, the ship will keep track of the number of lives it has and offer us a way to tell it that it has been killed. Listing 12-8 shows you the code.

public class Ship extends DynamicGameObject3D { static float SHIP_VELOCITY = 20f; static int SHIP_ALIVE = 0; static int SHIP_EXPLODING = 1; static float SHIP_EXPLOSION_TIME = 1.6f; static float SHIP_RADIUS = 0.5f;

We start off with a couple of constants defining the maximum ship velocity, two states (alive and exploding), the amount of time it takes the ship to fully explode, and the ship's bounding sphere radius. We also let the class derive from DynamicGameObject3D since it has a position and bounding sphere as well as a velocity. The acceleration vector stores in a DynamicGameObject3D will again be unused.

int lives; int state;

float stateTime = 0;

Next we have the members, consisting of two integers to keep track of the number of lives the ship has and its states (either SHIP_ALIVE or SHIP_EXPLODING). The last member keeps track of how many seconds the ship has been in its current state.

public Ship(float x, float y, float z) { super(x, y, z, SHIP_RADIUS); lives = 3; state = SHIP_ALIVE;

The constructor performs the usual super class constructor call and initializes some of the members. Our ship will have a total of three lives.

public void update(float deltaTime, float accelY) { if (state == SHIP_ALIVE) {

velocity.set(accelY / 10 * SHIP_VELOCITY, 0, 0); position.add(velocity.x * deltaTime, 0, 0); if (position.x < World.WORLD_MIN_X) position.x = World.WORLD_MIN_X; if (position.x > World.WORLD_MAX_X) position.x = World.WORLD_MAX_X; bounds.center.set(position); } else {

if (stateTime >= SHIP_EXPLOSION_TIME) { lives-- ; stateTime = 0; state = SHIP_ALIVE;

stateTime += deltaTime;

The update() method is pretty simple. It takes the delta time as well as the current accelerometer reading on the y-axis of the device (remember, we are in landscape mode, so the accelerometer y-axis is our screen's x-axis). If the ship is alive, we set its velocity based on the accelerometer value (which will be in the range -10 to 10) just as we did for Bob in Super Jumper. Additionally, we update its position based on the current velocity. Next we check whether the ship has left the boundaries of the playing field, using two constants we'll define in our World class later on. When the position is fixed up we can finally update the center of the bounding sphere of the ship.

In case the ship is exploding we check for how long that's been the case. After 1.6 seconds in the exploding state the ship is finished exploding, loses one life, and goes back to the alive state.

Finally we just update the stateTime member based on the given delta time.

public void kill() {

state = SHIP_EXPLODING; stateTime = 0; velocity.x = 0;

The last kill() method will be called by the World class if it determines a collision between the ship and a shot or an invader. It will set the state to exploding, reset the state time and make sure that the ship's velocity is zero on all axes (we never set the y-and z-component of the velocity vector, since we only move on the x-axis).

0 0