• $19 Game Dev' Courses - Use code "FEBUDEMY"

    Video courses

Unity Pro Development A to Z – Build 10 Android/iOS Games

The Complete Android & Java Developer Course – Build 21 Apps

The Complete Java Developer Course. Learn Step by Step

¿Español : Codificar un juego tipo Space Invaders para Android

Welcome to the Space Invaders coding project for Android. In this game project, we will step through everything you need to know to have a fully playable Space Invaders clone running on your Android phone or tablet. The wave of invaders is genuinely challenging yet achievable and it would be simple for you to extend this project to add extra features like increasingly difficult waves, high scores or perhaps add a flying saucer-like in the original arcade classic.

  • Learning java by building Android games

    Learning Java by Building Android Games

    Want to learn Java for Android? Even if you are completely new to either Java, Android, or game programming but are aiming to publish Android games, then this book is for you. This book also acts as a refresher for those who already have experience in Java on other platforms or other object-oriented languages.
    • Setup your own Android game programming environment using Android Studio
    • Control logic, branch your code, and add real decision-making depth to your games
    • Design and use 2d sprite animations, smooth pixel graphics, sound FX, simple collision detection and artificial intelligence (AI)
    • Build around a dozen sample test apps and 4 complete working games!
    Amazon USA
    Amazon UK
    Amazon CA
    Our Store (US only)
    small_book

    Android Game Programming by Example

    Learn to build exciting Android game projects. Build a simple flappy-bird like game to a multi-environment, tough, retro platformer then an OpenGL ES 2 Asteroids clone, running at hundreds of frames per second .
    • Animate your characters with sprite sheets, add multiple scrolling parallax backgrounds, and implement genuinely tough, playable levels in your games
    • Every single line of code is printed in the book! No need to refer to the code files while trying to follow along. All the code files are also supplied separately so you can refer to them in their completed form and copy/paste them into your project if you like.
    • Implement a multitude of other game features such as pickups, firing weapons, HUD’s, generating and playing sound FX, scenery, level transition, high scores, and more
    Amazon USA
    Amazon UK
    Amazon CA
    Our Store (US Only)

About this project

Skill level 1
Time to complete 1 hour

New Concepts:

  1. Internal animation timing to make the Invaders flap their arms
  2. Using an external class for the view of the game
  3. Enemies that think, move and take aim

Recommended preparation tutorials

Getting started

The finished game will allow the player to move left and right by holding the corresponding side of the screen near the bottom. As the player also needs to shoot at the invaders we will respond to when the screen is touched slightly higher than the lower part as well. The Invaders will slide across the screen flapping their arms and spitting bullets. If they hit a player he loses a life if they hit a shelter it will crumble until eventually the player has nowhere to hide. When the invaders reach the side of the screen they will drop down and scroll back the other way; a little bit faster. Eventually they will be moving so fast the player is doomed. The space invaders must be taken out quickly and efficiently to survive.

To get started create a new project in Android Studio, call it Space Invaders and name the Activity SpaceInvadersActivity then read on because we will do things slightly differently compared to the Breakout project.

Making the game full-screen landscape

We want to use every pixel that the device has to offer so we will make changes to the app’s AndroidManifest.xml configuration file.

  1. In the project explorer pane in Android Studio double click on the manifests folder, this will open up the AndroidManifest.xml file in the code editor.
  2. In the AndroidManifest.xml file, locate the following line of code,  android:name=".SpaceInvadersActivity">
  3. Place the cursor before the closing > shown above. Tap the enter key a couple of times to move the > a couple of lines below the rest of the line shown above.
  4. Immediately below SpaceInvadersActivity but BEFORE the newly positioned > type or copy and paste these two lines to make the game run full screen and lock it in the landscape orientation.
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:screenOrientation="landscape"

Let’s talk a bit about the assets we will use in Space Invaders.

Also, note that all the bonus downloads for this and every future tutorial is available on an exclusive download area for my Patreon subscribers.

patreon-medium-banner

The Graphics

In this project, we will use a mixture of bitmaps from external graphics files for the invaders and player ship and use the Canvas class’ drawRect method to represent the lasers and the shelters. Something worth mentioning at this point is that even the classes that use bitmaps will still have a RectF object because although we don’t need it for drawing we can still use it for collision detection. More on this later in the project.

Before we get coding we want to add the player ship graphic and two different graphics for the two frames of animation for our invader to our project files so we can use them in our  code. The graphics are white so they are displayed below on a blue background. Here they are.

The Space Invaders player ship graphic

The Space Invaders player ship graphic

The first frame of animation for the invader

The first frame of animation for the invader

The second frame of animation for the invader

The second frame of animation for the invader

 

You can download them by right-clicking on the images then select the Save image as… option. Just make sure the file names are kept the same. They are named playership.pnginvader1.png and invader2.png. Add the graphics to the drawable folder within your Android Studio folders.

The sound

We will have a menacing two-tone sound to represent the invader’s movement. This sound will speed up as the invaders speed up. I have called these two sounds “uh” and “oh” because if we were attacked by invaders we might say, “uh oh”. We also need sounds for shooting a laser, the player being hit, an invader being hit and a shelter being damaged.

Of course, we need to add the sound files to our project. You can create your own or download mine by right-clicking on the files listed below. Just make sure you use exactly the same file names. You can also listen to each of the sounds by using the media controls below each of the links.

uh.ogg

 

shoot.ogg

 

playerexplode.ogg

 

oh.ogg

 

invaderexplode.ogg

 

damageshelter.ogg

When you have your preferred sound FX, using your operating system’s file browser go to the app\src\main folder of the project and create a folder called assets. Add your sound file to this folder.

The class structure

For this project, we will vary slightly from the structure of the Breakout project. But far from adding complexity, we will see how by separating out further the code in the different files we will make our Space Invaders project simpler to write, manage and extend.

Each game object will be represented by its own class. So we will have one for the player’s ship, one for an invader, a bullet and the brick of a defence shelter. Furthermore, we will also take the inner class which represents the view of the game and make it a class in its own right. It will be called SpaceInvadersView. This changes nothing about how we code it internally but it does make the whole project more manageable.

We want to create classes to represent the view and the game objects we have just discussed. We will require the following classes.  SpaceInvadersView, Invader, PlayerShip, DefenceBrick and  Bullet. By creating empty implementations of all these classes we can then declare objects of them in SpaceInvadersView right away. This avoids constantly revisiting SpaceInvadersView to add new declarations. All we will need to do is implement each object, in turn, initialize it, update it and draw it.

With this in mind let’s create those empty classes. Now, Right-click the java folder in the Android Studio project explorer as shown in the next image.

Creating a new Java class called Paddle

Creating a new Java class called

Now select New|Java class then select …\app\source\main\java and click OK. Now enter SpaceInvadersView as the name for our new class and click OK. We have now created a new Java class in a separate file called SpaceInvadersView.java. As previously mentioned the class is not an inner class as the view was in the Breakout project.  This helps us to compartmentalize our code and keep it organized into logical areas to a greater extent than we did previously.

Now do the same and create new classes for  PlayerShip, Bullet, DefenceBrick, and Invader classes. You should now have six classes in total including SpaceInvadersActivity. Just for clarity, the code for each of the five new classes is shown below (excluding the package declaration at the top of each class). We will then look at each of the classes, in turn, starting with SpaceInvadersActivity.

SpaceInvadersView

public class SpaceInvadersView{

}

PlayerShip

public class PlayerShip {

}

Bullet

public class Bullet {

}

DefenceBrick

public class DefenceBrick {

}

Invader

public class Invader {

}

Coding the Space Invaders Activity class

There is nothing new here compared to the Activity class from the Breakout project. The only difference is that there is no inner class extending SurfaceView. Notice that we still create a new object of type SpaceInvadersView and set it as the view for the screen. We also get the screen resolution and pass this information into the  SpaceInvadersView constructor method. The code below will show some errors until we implement the SpaceInvadersView class.

Tip: We will be using plenty of classes from the Android API in this project. You can use the Android Studio shortcut Alt + Enter while the mouse cursor is hovered over any Android class which is showing an error. This will add the appropriate import… line at the top of the file.

Delete the default code that was auto-generated from SpaceInvadersActivity then add the code below.

import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;

// SpaceInvadersActivity is the entry point to the game.
// It will handle the lifecycle of the game by calling
// methods of spaceInvadersView when prompted to so by the OS.
public class SpaceInvadersActivity extends Activity {

    // spaceInvadersView will be the view of the game
    // It will also hold the logic of the game
    // and respond to screen touches as well
    SpaceInvadersView spaceInvadersView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Get a Display object to access screen details
        Display display = getWindowManager().getDefaultDisplay();
        // Load the resolution into a Point object
        Point size = new Point();
        display.getSize(size);

        // Initialize gameView and set it as the view
        spaceInvadersView = new SpaceInvadersView(this, size.x, size.y);
        setContentView(spaceInvadersView);

    }

    // This method executes when the player starts the game
    @Override
    protected void onResume() {
        super.onResume();

        // Tell the gameView resume method to execute
        spaceInvadersView.resume();
    }

    // This method executes when the player quits the game
    @Override
    protected void onPause() {
        super.onPause();

        // Tell the gameView pause method to execute
        spaceInvadersView.pause();
    }
}

Now we have a working Activity class that is the entry point to our Space Invaders game. It will simply get the screen resolution, pass it to SpaceInvadersView where all the game action will take place. SpaceInvadersActivity will not do anything unless it gets a message from the operating system to say it is being shut down or restarted; in which case it will call the pause and resume methods of SpaceInvadersView which will shut down or start the main game thread.

Coding the Space Invaders view class outline

As we have already created a bunch of empty classes we can flesh out our game engine along with a whole bunch of the key variable and object declarations right away. I have broken the starting code for this class into a number of sections as the code is quite lengthy. However, there is not much that we didn’t already see in the last project.

The SpaceInadersView declaration and member variables

First of all, in the next block of code we see that the class declaration needs to be modified to extend SurfaceView and implement Runnable to provide our drawing and threading functionality. We then see a bunch of familiar member objects and variables for handling our thread, drawing, main game loop, frame rate, and screen resolution. The comments should act as a reminder to what does what.

Starting with the declaration of the playerShip object we see the Space Invaders specific declarations. We have an object of PlayerShip and one of Bullet which will unsurprisingly represent the player’s ship and his solitary bullet. We then have an array of Bullet objects called invadersBullets along with a couple of variables nextBullet and maxInvaderBullets to help us manage this array.

After this we then declare an array to hold a whole army of Invader objects and again, a variable to help us manage the array. Then we have an array of DefenceBrick objects. We will see how we construct and destroy the player’s shelters from this array later.

Following that we have the usual SoundPool object and a  int to represent each of the sound FX we will want to play. Then we have an int to represent score and a  int to represent lives. The last variables we declare are new and we will see near the end of the project how we use menaceInterval, uhOrOh and lastMenaceTime to time the flapping of the invader’s arms and the speed of the “uh oh” sound FX.

public class SpaceInvadersView extends SurfaceView implements Runnable{

    Context context;

    // This is our thread
    private Thread gameThread = null;

    // Our SurfaceHolder to lock the surface before we draw our graphics
    private SurfaceHolder ourHolder;

    // A boolean which we will set and unset
    // when the game is running- or not.
    private volatile boolean playing;

    // Game is paused at the start
    private boolean paused = true;

    // A Canvas and a Paint object
    private Canvas canvas;
    private Paint paint;

    // This variable tracks the game frame rate
    private long fps;

    // This is used to help calculate the fps
    private private long timeThisFrame;

    // The size of the screen in pixels
    private int screenX;
    private int screenY;

    // The players ship
    private PlayerShip playerShip;

    // The player's bullet
    private Bullet bullet;

    // The invaders bullets
    private Bullet[] invadersBullets = new Bullet[200];
    private int nextBullet;
    private int maxInvaderBullets = 10;

    // Up to 60 invaders
    Invader[] invaders = new Invader[60];
    int numInvaders = 0;

    // The player's shelters are built from bricks
    private DefenceBrick[] bricks = new DefenceBrick[400];
    private int numBricks;

    // For sound FX
    private SoundPool soundPool;
    private int playerExplodeID = -1;
    private int invaderExplodeID = -1;
    private int shootID = -1;
    private int damageShelterID = -1;
    private int uhID = -1;
    private int ohID = -1;

    // The score
    int score = 0;

    // Lives
    private int lives = 3;

    // How menacing should the sound be?
    private long menaceInterval = 1000;
    // Which menace sound should play next
    private boolean uhOrOh;
    // When did we last play a menacing sound
    private long lastMenaceTime = System.currentTimeMillis();

Declaring all the variables we just have will make progress through the rest of the project much faster.

The SpaceInvadersView constructor

The constructor is the first method we will implement. The constructor is the method called from SpaceInvadersActivity in the code spaceInvadersView = new SpaceInvadersView(this, screenX, screenY). So the first thing we notice is the signature of the method which receives the variables passed in.

As before we call the parent class ( SurfaceView) to help set up our object with the code super(context). The next line is new. this.context = context copies the Context object passed into the constructor to the SpaceInvadersView own context object. This makes it available throughout the class and not just in the constructor. The rest of the constructor we have seen in the last project. We simply initialize screenX and screenY then prepare our sound files ready to be played.

Finally in the constructor we call the prepareLevel method which is where we will initialize all our game objects and get ready to play the game. Notice in the implementation of prepareLevel there is a bunch of comments that indicate where code we have yet to write will eventually go. Add all the code in the constructor and prepareLevel immediately after the previous block of code. Be sure to include the comments in prepareLevel as reference points for the code we will soon write.

    // When the we initialize (call new()) on gameView
    // This special constructor method runs
    public SpaceInvadersView(Context context, int x, int y) {

        // The next line of code asks the
        // SurfaceView class to set up our object.
        // How kind.
        super(context);

        // Make a globally available copy of the context so we can use it in another method
        this.context = context;

        // Initialize ourHolder and paint objects
        ourHolder = getHolder();
        paint = new Paint();

        screenX = x;
        screenY = y;

        // This SoundPool is deprecated but don't worry
        soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC,0);

        	try{
		// Create objects of the 2 required classes
		AssetManager assetManager = context.getAssets();
		AssetFileDescriptor descriptor;

		// Load our fx in memory ready for use
		descriptor = assetManager.openFd("shoot.ogg");
		shootID = soundPool.load(descriptor, 0);

		descriptor = assetManager.openFd("invaderexplode.ogg");
		invaderExplodeID = soundPool.load(descriptor, 0);

		descriptor = assetManager.openFd("damageshelter.ogg");
		damageShelterID = soundPool.load(descriptor, 0);

		descriptor = assetManager.openFd("playerexplode.ogg");
		playerExplodeID = soundPool.load(descriptor, 0);

		descriptor = assetManager.openFd("damageshelter.ogg");
		damageShelterID = soundPool.load(descriptor, 0);

		descriptor = assetManager.openFd("uh.ogg");
		uhID = soundPool.load(descriptor, 0);

		descriptor = assetManager.openFd("oh.ogg");
		ohID = soundPool.load(descriptor, 0);

	}catch(IOException e){
		// Print an error message to the console
		Log.e("error", "failed to load sound files");
	}

        prepareLevel();
    }

    private void prepareLevel(){

        // Here we will initialize all the game objects

        // Make a new player space ship

        // Prepare the players bullet

        // Initialize the invadersBullets array

        // Build an army of invaders

        // Build the shelters

    }

We are making good progress. We just need to add some of the usual suspects (methods) to the project and then we can get on with coding our first game object.

The usual game-loop methods: run, update, and draw

Next, we will add a whole bunch of methods that we have seen before when we looked at coding a basic game loop and coding a Breakout game. However, notice all placeholder comments that will be invaluable for locating where the code we will soon write needs to go. Add the methods below right after the prepareLevel method.

@Override
public void run() {
	while (playing) {

		// Capture the current time in milliseconds in startFrameTime
		long startFrameTime = System.currentTimeMillis();

		// Update the frame
		if(!paused){
			update();
		}

		// Draw the frame
		draw();

		// Calculate the fps this frame
		// We can then use the result to
		// time animations and more.
		timeThisFrame = System.currentTimeMillis() - startFrameTime;
		if (timeThisFrame >= 1) {
			fps = 1000 / timeThisFrame;
		}

		// We will do something new here towards the end of the project

}

    private void update(){

        // Did an invader bump into the side of the screen
        boolean bumped = false;

        // Has the player lost
        boolean lost = false;

        // Move the player's ship

        // Update the invaders if visible

        // Update all the invaders bullets if active

        // Did an invader bump into the edge of the screen

        if(lost){
            prepareLevel();
        }

        // Update the players bullet

        // Has the player's bullet hit the top of the screen

        // Has an invaders bullet hit the bottom of the screen

        // Has the player's bullet hit an invader

        // Has an alien bullet hit a shelter brick

        // Has a player bullet hit a shelter brick

        // Has an invader bullet hit the player ship

    }

    private void draw(){
        // Make sure our drawing surface is valid or we crash
        if (ourHolder.getSurface().isValid()) {
            // Lock the canvas ready to draw
            canvas = ourHolder.lockCanvas();

            // Draw the background color
            canvas.drawColor(Color.argb(255, 26, 128, 182));

            // Choose the brush color for drawing
            paint.setColor(Color.argb(255,  255, 255, 255));

            // Draw the player spaceship

            // Draw the invaders

            // Draw the bricks if visible

            // Draw the players bullet if active

            // Draw the invaders bullets if active

            // Draw the score and remaining lives
            // Change the brush color
            paint.setColor(Color.argb(255,  249, 129, 0));
            paint.setTextSize(40);
            	canvas.drawText("Score: " + score + "   Lives: " + lives, 10,50, paint);

            // Draw everything to the screen
            ourHolder.unlockCanvasAndPost(canvas);
        }
    }

A few more methods that we have seen before follow next.

More of the usual suspects: pause, resume, and onTouchEvent

Add these methods which start and stop our thread and will eventually detect the player’s input.

    	// If SpaceInvadersActivity is paused/stopped
	// shutdown our thread.
	public void pause() {
		playing = false;
		try {
			gameThread.join();
		} catch (InterruptedException e) {
			Log.e("Error:", "joining thread");
		}

	}

    // If SpaceInvadersActivity is started then
    // start our thread.
    public void resume() {
        playing = true;
        gameThread = new Thread(this);
        gameThread.start();
    }

    // The SurfaceView class implements onTouchListener
    // So we can override this method and detect screen touches.
    @Override
    public boolean onTouchEvent(MotionEvent motionEvent) {

	switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {

            // Player has touched the screen
            case MotionEvent.ACTION_DOWN:

                break;

            // Player has removed finger from screen
            case MotionEvent.ACTION_UP:

                break;
        }
        return true;
    }
}

Now we can run the Space Invaders game and see just the score and a plain background.

The first runnable screen shot of the Android Space Invaders project

The first runnable screen shot of the Android Space Invaders project

Now we have the outline to our SpaceInvadersView class let’s build the players spaceship.

Implementing the PlayerShip class

First of all we have an  RectF instance that will be used for collision detection, then we have an  Bitmap object into which we will load the playership.png graphic, a float for each of the height and length,  a float for the x and y coordinates of the spaceship on the screen and another float, shipSpeed which is how many pixels per second the ship can move.

After that we have three final int members STOPPED, LEFT and RIGHT which are public and can, therefore, be accessed from the SpaceInvadersView class to tell the spaceship which way to move. Then we have shipMoving which will be assigned one of the aforementioned final values and this is used internally in the update method of this class to determine which way to move if any.

Add all these member variables and objects just after the class declaration.

 RectF rect;

    // The player ship will be represented by a Bitmap
    private Bitmap bitmap;

    // How long and high our ship will be
    private float length;
    private float height;

    // X is the far left of the rectangle which forms our ship
    private float x;

    // Y is the top coordinate
    private float y;

    // This will hold the pixels per second speed that the ship will move
    private float shipSpeed;

    // Which ways can the ship move
    public final int STOPPED = 0;
    public final int LEFT = 1;
    public final int RIGHT = 2;

    // Is the ship moving and in which direction
    private int shipMoving = STOPPED;

Here is the PlayerShip constructor where we set up our PlayerShip class ready to defend the Earth. Notice the method parameters receive a Context and the screen’s horizontal and vertical resolution. We will see how we use these soon.

First, we initialize rect as a blank rectangle. It will become apparent how this object is useful soon when we implement the update method. We initialize length and height by dividing the screen resolution on the horizontal and vertical axes by ten. Ten is an arbitrary value but it works well. For a smaller ship, increase the number for a bigger ship decrease the number.

Next, we initialize x and y to the middle of the screen horizontally and just above the bottom vertically. The x and y variables actually refer to the top left pixel of the spaceship so dividing screenX by two is not exactly the middle but it is good enough.

Now we load bitmap with the .png file using BitmapFactory.decodeResource and after that, we scale bitmap to the correct length and height using Bitmap.createScaledBitmap method.

Finally, for the constructor, we initialize the speed of our spaceship. Add this code just after the previous block of code.

// This the the constructor method
    // When we create an object from this class we will pass
    // in the screen width and height
    public PlayerShip(Context context, int screenX, int screenY){

        // Initialize a blank RectF
        rect = new RectF();

        length = screenX/10;
        height = screenY/10;

        // Start ship in roughly the screen centre
        x = screenX / 2;
        y = screenY - 20;

        // Initialize the bitmap
        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.playership);

        // stretch the bitmap to a size appropriate for the screen resolution
        bitmap = Bitmap.createScaledBitmap(bitmap,
                (int) (length),
                (int) (height),
                false);

        // How fast is the spaceship in pixels per second
        shipSpeed = 350;
    }

Here are some getters and setters so that SpaceInvadersView can grab a copy of rect for collision detection, bitmap for drawing the spaceship, x and length for firing bullets dead-centre from the ship and the setter setMovementState gives onTouchEvent the ability to determine which way the ship should move each time update is called.

Add these methods below the last block of code then we can look at the update method.

public RectF getRect(){
        return rect;
    }

    // This is a getter method to make the rectangle that
    // defines our ship available in SpaceInvadersView class
    public Bitmap getBitmap(){
        return bitmap;
    }

    public float getX(){
        return x;
    }

    public float getLength(){
        return length;
    }

    // This method will be used to change/set if the ship is going left, right or nowhere
    public void setMovementState(int state){
        shipMoving = state;
    }

And here is the last method of the PlayerShip class called update. It is very simple in the beginning and we have seen before how we update the x variable by shipSpeed divided by the current frame rate the game is running at and dependent upon the value of shipMoving. But what happens next is the key to how we detect collisions for our spaceship. We update the starting and ending horizontal and vertical positions of rect with the x and y locations of the spaceship. We know the ending locations simply by adding height to y and length to x. Now whenever SpaceInvadersActivity calls getRect it will get an  RectF object which effectively wraps the player’s spaceship. This RectF can then be used in the RectF.intersects method in exactly the same way it was in the Breakout game. Add the update method to the PlayerShip class.

  // This update method will be called from update in SpaceInvadersView
    // It determines if the player ship needs to move and changes the coordinates
    // contained in x if necessary
    public void update(long fps){
        if(shipMoving == LEFT){
            x = x - shipSpeed / fps;
        }

        if(shipMoving == RIGHT){
            x = x + shipSpeed / fps;
        }

        // Update rect which is used to detect hits
        rect.top = y;
        rect.bottom = y + height;
        rect.left = x;
        rect.right = x + length;

    }

That’s it for the PlayerShip class. Now we can put it to work in three stages. First, we will initialize one in the prepareLevel method, then we will call its update method from update and then we will draw it in the draw method. We won’t be able to move the ship however until we fully implement the onTouchEvent method which we will do after we have implemented the Bullet class.

Enter this code in the prepareLevel method in the place indicated by the comment.

        // Make a new player space ship
        playerShip = new PlayerShip(context, screenX, screenY);

Enter this code in the update method in the place indicated by the comment.

        // Move the player's ship
        playerShip.update(fps);

Enter this code in the draw method in the place indicated by the comment.

            // Now draw the player spaceship
            canvas.drawBitmap(playerShip.getBitmap(), playerShip.getX(), screenY - 50, paint);

If you run the game you will see the spaceship at the bottom of the screen.

The ship only

The ship only

Now we can implement the Bullet class

Shooting bullets

First, we add some member variables. An x and y to hold the bullet’s location on the screen. a RectF which will be used to both draw and detect collisions on a bullet. Two final int variables; UP and DOWN that SpaceInvadersView can use to control the direction of a bullet and heading which will hold one of those values; we initially initialize to -1 because it is going nowhere at the moment. The speed variable is initialized to 350. This is the pixels per second that the bullet will travel at. This is quite fast and presents a challenge even on a medium resolution tablet. All bullets have a width and a height. The width is initialized right away to 1 pixel, height will be initialized in the constructor and will be relative to the resolution of the screen. The last variable is a boolean isActive. We can set this to  true and false as needed so we know when to draw and update each bullet and when we don’t need to bother.

Finally in the block of code below we have the constructor which initializes y as previously described, sets isActive to false and initializes a blank RectF object. Enter the code below in the Bullet class.

    private float x;
    private float y;

    private RectF rect;

    // Which way is it shooting
    public final int UP = 0;
    public final int DOWN = 1;

    // Going nowhere
    int heading = -1;
    float speed =  350;

    private int width = 1;
    private int height;

    private boolean isActive;

    public Bullet(int screenY) {

        height = screenY / 20;
        isActive = false;

        rect = new RectF();
    }

Next, we have a bunch of getters and setters that pass rect back to SpaceInvadersView for collision detection and drawing, returns the status ( isActive true or false) which as we will see is useful for knowing when to draw and check for collisions and finally we have a getImpactPointY method which returns the tip pixel of the bullet. This will be different depending on whether the bullet is heading down (fired by an invader) or up (fired by player). Enter the getters and setters we have just discussed below the previous block of code.

    public RectF getRect(){
        return  rect;
    }

    public boolean getStatus(){
        return isActive;
    }

    public void setInactive(){
        isActive = false;
    }

    public float getImpactPointY(){
        if (heading == DOWN){
            return y + height;
        }else{
            return  y;
        }

    }

Next, we have the important shoot method which works by first confirming that the bullet is NOT already active. If it is already active, the launch of the bullet fails. Otherwise, a starting x and y location are initialized, the heading is set and the bullet is set to isActive = true. We return true to the calling code so further actions can be taken for a successful bullet launch; namely playing a sound and keeping track of the invadersBullets array. If the bullet was already active at the time this method was called the code returns false to let the calling code know that a new bullet launch was not possible.

Enter the shoot method below the previous block of code.

    public boolean shoot(float startX, float startY, int direction) {
        if (!isActive) {
            x = startX;
            y = startY;
            heading = direction;
            isActive = true;
            return true;
        }

        // Bullet already active
        return false;
    }

Of course, this class will also need a  update method. Notice that we update x and y in the usual way and also update rect so it is up-to-date for drawing and collision detection when required. Enter the update method into the Bullet class.

    public void update(long fps){

        // Just move up or down
        if(heading == UP){
            y = y - speed / fps;
        }else{
            y = y + speed / fps;
        }

        // Update rect
        rect.left = x;
        rect.right = x + width;
        rect.top = y;
        rect.bottom = y + height;

    }

Now we just need to initialize, update and draw the bullets. Obviously, we won’t actually see any bullets until we implement a fire button for the player’s single bullet and the Invader class which will trigger the firing of the enemy bullets.

Notice in the next three blocks of code that we keep the single player’s bullet ( bullet) and the array of bullets ( invaderBullets) the invaders will use separately. We don’t want to waste time doing collision detection on the invader’s bullets against the invaders themselves so it is good to know which bullet belongs to which protagonist. Although we will detect the player damaging his own shelter as this feature was in the original arcade classic.

Enter this code in the prepareLevel method in the place indicated by the comment.

        // Prepare the players bullet
        bullet = new Bullet(screenY);

        // Initialize the invadersBullets array
        for(int i = 0; i < invadersBullets.length; i++){
            invadersBullets[i] = new Bullet(screenY);
        }

Enter this code in the update method in the place indicated by the comments.

        // Update the players bullet
        if(bullet.getStatus()){
            bullet.update(fps);
        }

        // Update all the invaders bullets if active
        for(int i = 0; i < invadersBullets.length; i++){
            if(invadersBullets[i].getStatus()) {
                invadersBullets[i].update(fps);
            }
        }

Enter this code in the draw method in the place indicated by the comments.

            // Draw the players bullet if active
            if(bullet.getStatus()){
                canvas.drawRect(bullet.getRect(), paint);
            }

            // Draw the invaders bullets

            // Update all the invader's bullets if active
            for(int i = 0; i < invadersBullets.length; i++){
                if(invadersBullets[i].getStatus()) {
                    canvas.drawRect(invadersBullets[i].getRect(), paint);
                }
            }

Now we can implement the player controls to let him move and shoot.

Giving the player control

In the next block of code, I show the entire onTouchEvent method including the code we fleshed out near the start of the project. In it, you can see that we set paused to false in the ACTION_DOWN case. Also in  ACTION_DOWN case we detect any touches in the bottom eighth of the screen ( if(motionEvent.getY() > screenY - screenY / 8)) then further test which side of the screen the touch was and call setMovementState with the appropriate public final int  to update which way the player’s spaceship will travel.

After this, still in  ACTION_DOWN case we detect if a touch occurs ABOVE the bottom eighth of the screen ( if(motionEvent.getY() > screenY - screenY / 8)) and if so we call shoot on bullet passing in the coordinates of the top centre of the player’s ship. If shoot returns true then a bullet is launched and a sound FX is played.

In the next case, ACTION_UP we simply stop the ship moving by passing STOPPED into setMovementState.

@Override
public boolean onTouchEvent(MotionEvent motionEvent) {

	switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {

		// Player has touched the screen
		case MotionEvent.ACTION_DOWN:

			paused = false;

			if(motionEvent.getY() > screenY - screenY / 8) {
				if (motionEvent.getX() > screenX / 2) {
					playerShip.setMovementState(playerShip.RIGHT);
				} else {
					playerShip.setMovementState(playerShip.LEFT);
				}

			}

			if(motionEvent.getY() < screenY - screenY / 8) {
				// Shots fired
				if(bullet.shoot(playerShip.getX()+
					playerShip.getLength()/2,screenY,bullet.UP)){
						soundPool.play(shootID, 1, 1, 0, 0, 1);
					}
				}
				break; 			 		

		// Player has removed finger from screen
		case MotionEvent.ACTION_UP: 	

			if(motionEvent.getY() > screenY - screenY / 10) {
				playerShip.setMovementState(playerShip.STOPPED);
			}

			break;

	}

	return true;
}

You can now run the game, move the spaceship around by holding the screen on the bottom left and right. Furthermore, if you tap anywhere above the bottom eighth of the screen the player’s ship will fire a bullet. It will also play a laser shooting sound effect.

Let’s give the player something to shoot at.

Implementing the Invader class

This class like the PlayerShip class will have an  RectF object as well as an  Bitmap object for collision detection and drawing respectively. We will implement these features in exactly the same way. However, the Invader class will have a Bitmap for each frame of animation (arms up and arms down). We will see in this class that we have a getBitmap and a getBitmap2 method. We will see later in the draw method of SpaceInvadersView how we choose which one to call each frame.

With this in mind enter this code to declare all the objects and variables the Invader class will need.

RectF rect;

    Random generator = new Random();

    // The player ship will be represented by a Bitmap
    private Bitmap bitmap1;
    private Bitmap bitmap2;

    // How long and high our invader will be
    private float length;
    private float height;

    // X is the far left of the rectangle which forms our invader
    private float x;

    // Y is the top coordinate
    private float y;

    // This will hold the pixels per second speedthat the invader will move
    private float shipSpeed;

    public final int LEFT = 1;
    public final int RIGHT = 2;

    // Is the ship moving and in which direction
    private int shipMoving = RIGHT;

    boolean isVisible;

Next, we have the Invader constructor that initializes  rect as a blank rectangle, initializes length and width based on the screen resolution sets isVisible as  true because we want to see the invader unless it is shot. Notice how the x and y location on the screen is determined by the invader’s position in the invader army. A row and column number is passed into the constructor and this is used, along with an  padding of one twenty-fifth of the screens x resolution to determine the invader’s exact starting location.

Then in the constructor, we initialize and scale two Bitmap objects using the two graphics files. Finally, we set the speed to forty pixels per second. This will increase as the army of invaders make their way down to Earth.

public Invader(Context context, int row, int column, int screenX, int screenY) {

        // Initialize a blank RectF
        rect = new RectF();

        length = screenX / 20;
        height = screenY / 20;

        isVisible = true;

        int padding = screenX / 25;

        x = column * (length + padding);
        y = row * (length + padding/4);

        // Initialize the bitmap
        bitmap1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.invader1);
        bitmap2 = BitmapFactory.decodeResource(context.getResources(), R.drawable.invader2);

        // stretch the first bitmap to a size appropriate for the screen resolution
        bitmap1 = Bitmap.createScaledBitmap(bitmap1,
                (int) (length),
                (int) (height),
                false);

        // stretch the first bitmap to a size appropriate for the screen resolution
        bitmap2 = Bitmap.createScaledBitmap(bitmap2,
                (int) (length),
                (int) (height),
                false);

        // How fast is the invader in pixels per second
        shipSpeed = 40;
    }

Next, we have a bunch of getters, setters and helper methods. The first two below get and set the object as invisible and get the current state of visibility. The next two get the two bitmaps and return them to the code that called them. The next three,  getX  getY and getLength return the xy and length values respectively. These are used, as they were with PlayerShip to get precise coordinates at which to fire a bullet. Enter these getter and setter methods.

public void setInvisible(){
        isVisible = false;
    }

    public boolean getVisibility(){
        return isVisible;
    }

    public RectF getRect(){
        return rect;
    }

    public Bitmap getBitmap(){
        return bitmap1;
    }

    public Bitmap getBitmap2(){
        return bitmap2;
    }

    public float getX(){
        return x;
    }

    public float getY(){
        return y;
    }

    public float getLength(){
        return length;
    }

And of course, our Invader class needs a update method. This works in exactly the same way as it did for the PlayerShip class. Notice however that there is no code to handle the invader moving down. We will see this code next. Enter the code for the Invader class’ update method.

    public void update(long fps){
        if(shipMoving == LEFT){
            x = x - shipSpeed / fps;
        }

        if(shipMoving == RIGHT){
            x = x + shipSpeed / fps;
        }

        // Update rect which is used to detect hits
        rect.top = y;
        rect.bottom = y + height;
        rect.left = x;
        rect.right = x + length;

    }

The next method dropDownAndReverse does exactly as the name suggests. It swaps LEFT for RIGHT or vice versa then increases the invaders y coordinate by height which has the effect of moving it down the screen. Finally, the speed is increased by 18% by multiplying by 1.18. Enter the dropDownAndReverse method.

    public void dropDownAndReverse(){
        if(shipMoving == LEFT){
            shipMoving = RIGHT;
        }else{
            shipMoving = LEFT;
        }

        y = y + height;

        shipSpeed = shipSpeed * 1.18f;
    }

The takeAim method is kind of like our invader’s artificial intelligence. The first block of code in this method detects if the Invader object is approximately horizontally aligned with the player. If it is a random number is generated to produce a 1 in 150 chance of returning true to the calling code. As we will see shortly in the calling code, when true is returned an attempt to launch a bullet is made with a call to shoot.

If 1 in 150 doesn’t seem like very much chance that a shot will be fired just consider that this method will be called up to sixty times a second on one or maybe even two complete columns of invaders that return true to the initial if condition. So there will be loads of bullets flying when we run this code.

In the second block of code in this method, every invader is given a chance to unleash a shot no matter if they are aligned to the player or not. This is great for creating a hostile environment and taking out the shelters. As every single invader gets around sixty throws of the dice every second the odds have been changed to 1 in 2000. These are good variables to play with if you want to make the game harder or easier.

public boolean takeAim(float playerShipX, float playerShipLength){

	int randomNumber = -1;

	// If near the player
	if((playerShipX + playerShipLength > x &&
		playerShipX + playerShipLength < x + length) || (playerShipX > x && playerShipX < x + length)) {

		// A 1 in 500 chance to shoot
		randomNumber = generator.nextInt(150);
		if(randomNumber == 0) {
			return true;
		}

	}

	// If firing randomly (not near the player) a 1 in 5000 chance
	randomNumber = generator.nextInt(2000);
	if(randomNumber == 0){
		return true;
	}

	return false;
}

Initializing, drawing and updating the invaders

Now, as usual, we need to add code to the relevant places in SpaceInvadersView to bring our army of Invader objects to life.

Notice how we pass in row changing and column numbers to each successive Invader object in our array. And we keep track of the overall number of Invader objects in our array by incrementing numIvaders. Enter this code in the prepareLevel method in the place indicated by the comments.

        // Build an army of invaders
        numInvaders = 0;
        for(int column = 0; column < 6; column ++ ){
            for(int row = 0; row < 5; row ++ ){
                invaders[numInvaders] = new Invader(context, row, column, screenX, screenY);
                numInvaders ++;
            }
        }

This next block of code which updates our array of invaders each frame is quite lengthy but when examined closely it is not complicated. First, we loop through each and every invader and check if it is visible. If it is we call its update method and its coordinates will be updated. Next, we call takeAim on each and every invader in the array. Using the odds and aiming criteria specified in the takeAim method it might or might not return true. If it returns true we call shoot on the next bullet in the array as identified by nextBullet. If a bullet is successfully fired nextBullet is incremented ready for the next invader. We then check if nextBullet is equal to maxInvaderBullets and if it is we set nextBullet back to zero.

Back outside of the takeAim if block we check if the invader has touched either the left or right side of the screen and if it has we set bumped to true.

Enter the code we have just discussed in the update method in the place indicated by the comment.

// Update all the invaders if visible
for(int i = 0; i < numInvaders; i++){ 	

	if(invaders[i].getVisibility()) {
		// Move the next invader
		invaders[i].update(fps); 		 		 		

		// Does he want to take a shot?
		if(invaders[i].takeAim(playerShip.getX(),
			playerShip.getLength())){ 			 			 			

			// If so try and spawn a bullet
			if(invadersBullets[nextBullet].shoot(invaders[i].getX()
				+ invaders[i].getLength() / 2,
				invaders[i].getY(), bullet.DOWN)) { 				 				 				

				// Shot fired
				// Prepare for the next shot
				nextBullet++; 				 				 				

				// Loop back to the first one if we have reached the last
				if (nextBullet == maxInvaderBullets) {
					// This stops the firing of another bullet until one completes its journey
					// Because if bullet 0 is still active shoot returns false.
					nextBullet = 0;
				}
			}
		} 		 		 		

			// If that move caused them to bump the screen change bumped to true
			if (invaders[i].getX() > screenX - invaders[i].getLength()
				|| invaders[i].getX() < 0){

				bumped = true;

			}
	}

}

This next code handles how the invaders are triggered to drop down and start heading the other way. It also decreases the value of menaceInterval to make the invader arm waving and menacing sounds more frequent although we have a little more coding before this will take effect.

Enter this code in the update method immediately after the last block in the place indicated by the comment.

// Did an invader bump into the edge of the screen
if(bumped){

	// Move all the invaders down and change direction
	for(int i = 0; i < numInvaders; i++){
		invaders[i].dropDownAndReverse();
		// Have the invaders landed
		if(invaders[i].getY() > screenY - screenY / 10){
			lost = true;
		}
	}

	// Increase the menace level
	// By making the sounds more frequent
	menaceInterval = menaceInterval - 80;
}

Now we draw the invaders, notice the code we use to switch between the two different frames of animation. We will make this code fully functional in the section Timing the animation and the menacing sound.

Enter this code in the draw method in the place indicated by the comment.

            // Draw the invaders
            for(int i = 0; i < numInvaders; i++){
                if(invaders[i].getVisibility()) {
                    if(uhOrOh) {
                        canvas.drawBitmap(invaders[i].getBitmap(), invaders[i].getX(), invaders[i].getY(), paint);
                    }else{
                        canvas.drawBitmap(invaders[i].getBitmap2(), invaders[i].getX(), invaders[i].getY(), paint);
                    }
                }
            }

Now we can run the game and see the invaders move from side to side getting lower all the time.

Space Invaders with the player ship and the invaders drawn to the screen

Space Invaders with the player ship and the invaders drawn to the screen

At the moment, however, they are not waving their arms or sounding very menacing. We will fix this now.

Timing the animation and the menacing sound

Implement playing the uh-oh sound by adding this code right at the very end (inside the closing curly brace) of the run method. This will also trigger the invaders to start waving their hands. The code simply alternates the value of uhOrOh based on an ever decreasing (and therefore more frequent) value of menaceInterval.

// We will do something new here towards the end of the project
            // Play a sound based on the menace level
            if(!paused) {
                if ((startFrameTime - lastMenaceTime) > menaceInterval) {
                    if (uhOrOh) {
                        // Play Uh
                        soundPool.play(uhID, 1, 1, 0, 0, 1);

                    } else {
                        // Play Oh
                        soundPool.play(ohID, 1, 1, 0, 0, 1);
                    }

                    // Reset the last menace time
                    lastMenaceTime = System.currentTimeMillis();
                    // Alter value of uhOrOh
                    uhOrOh = !uhOrOh;
                }
            }

        }

Initialize the menacing variable in the prepareLevel method

        // Reset the menace level
        menaceInterval = 1000;

You can now play the game and the menacing sound and invader arm waving will speed up with every trip across the screen. Notice that the invaders will only fire ten bullets and the player just one before no more can be shot. We will shortly do some collision detection and reset the bullets at appropriate events to fix this.

Before we do let’s build the player some destructible shelters.

Implementing the DefenceBrick class.

The DefenceBrick class is really simple. It has a RectF and a  isVisible boolean variable. In the constructor the width and height are initialized based on the screen resolution as are all our other game objects. We also declare and initialize a brickPadding variable to 1, a shelterPadding variable to one-ninth of the screen width and a startHeight for the first brick of each shelter.

When we then initialize rect we combine these values with the row, column and shelterNumber to create the perfectly positioned brick within one of four shelters. Of course, another key to this code is how we call the DefenceBrick constructor. We will see that in a minute. Add this code to the DefenceBrick class.

private RectF rect;

private boolean isVisible;

public DefenceBrick(int row, int column, int shelterNumber, int screenX, int screenY){

	int width = screenX / 90;
	int height = screenY / 40;

	isVisible = true;

	// Sometimes a bullet slips through this padding.
	// Set padding to zero if this annoys you
	int brickPadding = 1;

	// The number of shelters
	int shelterPadding = screenX / 9;
    int startHeight = screenY - (screenY /8 * 2);

    rect = new RectF(column * width + brickPadding +
		(shelterPadding * shelterNumber) +
		shelterPadding + shelterPadding * shelterNumber,
		row * height + brickPadding + startHeight,
		column * width + width - brickPadding +
		(shelterPadding * shelterNumber) +
		shelterPadding + shelterPadding * shelterNumber,
		row * height + height - brickPadding + startHeight);
}

Here we have some simple getters and setters for DefenceBrick which get the rect object, set the object as invisible (for when it is destroyed) and get its current state of visibility. Add these three methods to the DefenceBrick class.

public RectF getRect(){
        return this.rect;
    }

    public void setInvisible(){
        isVisible = false;
    }

    public boolean getVisibility(){
        return isVisible;
    }

Now, as usual, we will add code to SpaceInvadersView bring our shelters to life. Note that we do not need any code in update because they do not move or think. We will see how we destroy a brick in update later on.

In the code below we have a triple nested for loop to loop through four shelters made up of 10 columns and five rows of DefenceBrick objects each.

Enter this code in the prepareLevel method in the place indicated by the comment.

        // Build the shelters
        numBricks = 0;
        for(int shelterNumber = 0; shelterNumber < 4; shelterNumber++){
            for(int column = 0; column < 10; column ++ ) {
                for (int row = 0; row < 5; row++) {
                    bricks[numBricks] = new DefenceBrick(row, column, shelterNumber, screenX, screenY);
                    numBricks++;
                }
            }
        }

Now we can just loop through the bricks array drawing any brick where getVisibility returns true.

Enter this code in the draw method in the place indicated by the comment.

            // Draw the bricks if visible
            for(int i = 0; i < numBricks; i++){
                if(bricks[i].getVisibility()) {
                    canvas.drawRect(bricks[i].getRect(), paint);
                }
            }

Run the game and we see that graphically we are finished.

Space Invaders with shelters added

Space Invaders with shelters added

We just need to handle all the different collisions.

Collision detection

There are five separate collision events that we need to detect and respond to. We will handle them each individually but each block of code can be entered straight into the update method in the locations indicated by the comments.

Here we check if the player’s bullet has hit the top of the screen. If it has we call setInactive making it invisible and available for shooting again. The code then loops through all the bullets in invadersBullets doing exactly the same.
Enter the code we have just discussed in the update method at the place indicated by the comment.

// Has the player's bullet hit the top of the screen
if(bullet.getImpactPointY() < 0){
	bullet.setInactive();
}

// Has an invaders bullet hit the bottom of the screen
for(int i = 0; i < invadersBullets.length; i++){
	if(invadersBullets[i].getImpactPointY() > screenY){
		invadersBullets[i].setInactive();
	}
}

In this next code, we check if the bullet is active and if it is we loop through each of the invaders. For each invader that is visible, we use RectF.intersects to check for a collision with the player’s bullet. When a collision is detected the invader is made invisible, we play an explosion sound, set the bullet to inactive and add ten to the score.
Enter the code we have just discussed in the update method at the place indicated by the comment.

        // Has the player's bullet hit an invader
        if(bullet.getStatus()) {
            for (int i = 0; i < numInvaders; i++) {
                if (invaders[i].getVisibility()) {
                    if (RectF.intersects(bullet.getRect(), invaders[i].getRect())) {
                        invaders[i].setInvisible();
                        soundPool.play(invaderExplodeID, 1, 1, 0, 0, 1);
                        bullet.setInactive();
                        score = score + 10;

                        // Has the player won
                        if(score == numInvaders * 10){
                            paused = true;
                            score = 0;
                            lives = 3;
                            prepareLevel();
                        }
                    }
                }
            }
        }

Now we loop through every alien bullet in the invadersBullets array. We check if it is active and if it is we loop through each and every brick in the bricks array and for each visible brick we call RectF.intersects to detect if they have collided. If they have the bullet is set to inactive, the brick is set to invisible and the sound effect indicating a shelter has been damaged is played. Note that each and every active bullet is checked against each and every visible brick. This is a significant amount of checks. We will discuss ways of improving on this in the next project.
Enter the code we have just discussed in the update method at the place indicated by the comment.

        // Has an alien bullet hit a shelter brick
        for(int i = 0; i < invadersBullets.length; i++){
            if(invadersBullets[i].getStatus()){
                for(int j = 0; j < numBricks; j++){
                    if(bricks[j].getVisibility()){
                        if(RectF.intersects(invadersBullets[i].getRect(), bricks[j].getRect())){
                            // A collision has occurred
                            invadersBullets[i].setInactive();
                            bricks[j].setInvisible();
                            soundPool.play(damageShelterID, 1, 1, 0, 0, 1);
                        }
                    }
                }
            }

        }

Here we do just the same as we did in the previous code block except we only check each brick against the player’s bullet. This is great for shooting a firing slit in the shelter.
Enter the code we have just discussed in the update method at the place indicated by the comment.

        // Has a player bullet hit a shelter brick
        if(bullet.getStatus()){
            for(int i = 0; i < numBricks; i++){
                if(bricks[i].getVisibility()){
                    if(RectF.intersects(bullet.getRect(), bricks[i].getRect())){
                        // A collision has occurred
                        bullet.setInactive();
                        bricks[i].setInvisible();
                        soundPool.play(damageShelterID, 1, 1, 0, 0, 1);
                    }
                }
            }
        }

Now for the last block of code in the whole Space Invaders project. This code loops through each and every active bullet in the invadersBullets array and checks to see if it has hit the player. If it has a life is deducted, a sound played and the bullet made inactive. Finally, a check is made in case the player has lost all their lives at which point the game is started again with a call to prepareLevel.
Enter the code we have just discussed in the update method at the place indicated by the comment.

        // Has an invader bullet hit the player ship
        for(int i = 0; i < invadersBullets.length; i++){
            if(invadersBullets[i].getStatus()){
                if(RectF.intersects(playerShip.getRect(), invadersBullets[i].getRect())){
                    invadersBullets[i].setInactive();
                    lives --;
                    soundPool.play(playerExplodeID, 1, 1, 0, 0, 1);

                    // Is it game over?
                    if(lives == 0){
                        paused = true;
                        lives = 3;
                        score = 0;
                        prepareLevel();

                    }
                }
            }
        }

Congratulations we are done!

The completed Space Invaders game running on an Android phone

The completed Space Invaders game running on an Android phone

Space Invaders final thoughts

The next project will have a scrolling world. That is the entire game area will not be drawn to the screen at one time. This will introduce the concept of a viewport which defines what the player can see at any given frame of play. We can also use the viewport to clip objects that don’t need updating or collision checking which in turn makes our code faster. Take a look a the Android 2D scrolling shooter project.

There is also a project you might be interested in to introduce a class to handle internal animations so we can have multiple objects all doing their own cool animations; like the Space Invaders arm waving but with an unlimited and a dynamic number of frames.

Please leave any comments below. Thanks and happy coding.

Please visit the Android category of our game coding bookstore for beginners