The PlayerShip object

We need to keep the model part of our code as separate as possible from the rest. We can do this by creating a class for our player's spaceship. Let's call our new class PlayerShip.

Go ahead and add a new class to the project, and call it PlayerShip. Here are a few quick steps on how to do that. Now, right-click the folder with our .java files in it and navigate to New | Java Class, then enter PlayerShip as the name and click on OK.

What do we need our PlayerShip class to be able to know about itself? As a bare minimum it needs to:

  • Know where it is on the screen
  • What it looks like
  • How fast it is flying

These requirements suggest a few member variables we can declare. Enter the code just after the class declaration that we generated:

private Bitmap bitmap;
private int x, y;
private int speed = 0;

As usual, use the Alt | Enter keyboard combination to import any missing classes. In the previous block of code, we see that we have declared an object of type Bitmap that we will use to hold the graphic which represents our ship.

We have also declared three int type variables; x and y to hold the spaceship's screen coordinates and another int type variable, speed to hold a value for how fast our spaceship is traveling.

Now, let's consider what our PlayerShip class needs to do. Again as a bare minimum it needs to:

  • Prepare itself
  • Update itself
  • Share it's state with our view

A constructor seems to be the ideal place to prepare itself. We can initialize its x and y coordinate variables and set a starting speed with the speed variable.

The other thing the constructor will need to do is to load the bitmap graphic, which represents its appearance. To load bitmaps, we require an Android Context object. This implies that the constructor that we write will need to receive a Context object from our view.

With all this in mind, here is our PlayerShip constructor to implement point one from our to-do list:

// Constructor
public PlayerShip(Context context) {
        x = 50;
        y = 50;
        speed = 1;
        bitmap = BitmapFactory.decodeResource 
        (context.getResources(), R.drawable.ship);

    }

As usual, we need to import some new classes using the Alt | Enter combination. After importing all the new classes required by the line which initializes our bitmap object, we can see we still have an error; Cannot resolve symbol ship.

Let's dissect the line that loads the ship bitmap as we will be seeing this quite a lot throughout the book.

The BitmapFactory class is using its static method decodeResource() to attempt to load our graphic of the player ship. It requires two parameters. The first is the getResources method supplied by the Context object that was passed from the view.

The second parameter R.drawable.ship is requesting a graphic called ship from the (R)esource folder named drawable. All we have to do to resolve this error is to copy our graphic, named ship.png, into the drawable folder of our project.

Simply drag and drop/copy and paste the ship.png graphic contained in the Chapter2/drawable folder from the download bundle into the res/drawable folder in the Android Studio project explorer window. The following is a ship.png image:

Number two on our list of things that PlayerShip needs to do is, to update itself. Let's implement a public update method that can be called from our TDView class. The method will simply increment the ship's x value by 1 each time it is called. Clearly, we need to get more advanced than this. For now implement the method in the PlayerShip class like this:

public void update() {
  x++;
}

Number three on the to-do list is to share its state with the view. We can do this by providing a bunch of getter methods like this:

//Getters
public Bitmap getBitmap() {
  return bitmap;
}

public int getSpeed() {
  return speed;
}

public int getX() {
  return x;
}

public int getY() {
  return y;
}

Now your TDView class can be instantiated, and find out what it likes about any PlayerShip objects. However, only the PlayerShip class itself can decide how it should look, what properties it has, and how it behaves.

We can see how we will draw our player's ship to the screen and animate it as well.