I had the intention to finally let the ship be mortal, but realized that the structure in GameEngine didn't really allow me to introduce a "GameOver" state without making the code really ugly.
So this chapter is instead dedicated to a re-factoring of GameEngine, in which we remove the "surfaceReady" flag and introduce the four different states "WAITING_FOR_SURFACE", "COUNTDOWN", "RUNNING" and "GAMEOVER" and switch-case constructions in both update() and draw().
So, here is the new GameEngine:
package com.ajomannen.justroids;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
public class GameEngine {
Context context;
Resources resources;
public float screenWidth;
public float screenHeight;
private Paint blackPaint;
private AsteroidHandler asteroidHandler;
private MissileHandler missileHandler;
private Ship ship;
private GameStatus gameStatus;
public static final int EVENT_NONE = 0;
public static final int EVENT_LEFT = 1;
public static final int EVENT_RIGHT = 2;
public static final int EVENT_THRUST = 3;
public static final int EVENT_FIRE = 4;
public int pendingEvent = EVENT_NONE;
// private boolean surfaceReady = false;
private static final int WAITING_FOR_SURFACE = 0;
private static final int COUNTDOWN = 1;
private static final int RUNNING = 2;
private static final int GAMEOVER = 3;
private int mode = WAITING_FOR_SURFACE;
public void Init(Context context) {
this.context = context;
resources = context.getResources();
blackPaint = new Paint();
blackPaint.setColor(Color.BLACK);
blackPaint.setStyle(Style.FILL);
gameStatus = new GameStatus();
}
private void setLevel(int level) {
gameStatus.setLevel(level);
asteroidHandler = new AsteroidHandler(resources, level);
missileHandler = new MissileHandler(resources);
ship = new Ship(resources, screenWidth / 2, screenHeight - 30, 0.1, 0,
0);
mode = COUNTDOWN;
}
public void onDestroy() {
try {
} catch (Exception e) {
}
}
// Rewritten
public void setSurfaceDimensions(int width, int height) {
screenWidth = width;
screenHeight = height;
if (mode == WAITING_FOR_SURFACE) {
setLevel(1);
}
}
// Rewritten
public void update() {
switch (mode) {
case WAITING_FOR_SURFACE: {
// Don't update anything. Just wait until setSurfaceDimensions() is called.
break;
}
case COUNTDOWN: {
// Just update gameStatus so the timer can tick up to zero
gameStatus.update();
if (gameStatus.getPassedLevelTime() > 0) {
pendingEvent = EVENT_NONE;
mode = RUNNING;
}
break;
}
case RUNNING: {
// Standard mode - update all objects
gameStatus.update();
asteroidHandler.update(screenWidth, screenHeight);
ship.update(screenWidth, screenHeight, asteroidHandler.asteroids,
pendingEvent, gameStatus);
missileHandler.update(screenWidth, screenHeight, pendingEvent,
ship, asteroidHandler.asteroids, gameStatus);
pendingEvent = EVENT_NONE;
if (asteroidHandler.asteroids.isEmpty()) {
setLevel(gameStatus.getLevel() + 1);
}
break;
}
case GAMEOVER: {
// Nothing here yet.
break;
}
}
}
// Rewritten
public void draw(Canvas canvas) {
switch (mode) {
case WAITING_FOR_SURFACE: {
// Don't draw anything before the surface is ready
break;
}
case COUNTDOWN: {
// No "break" here. We want the same draw:s during COUNTDOWN as
// during RUNNING
}
case RUNNING: {
// Standard mode - draw all objects
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(),
blackPaint);
asteroidHandler.draw(canvas);
missileHandler.draw(canvas);
ship.draw(canvas);
gameStatus.draw(canvas, screenHeight, screenWidth);
break;
}
case GAMEOVER: {
// Here we will add a nice little "Game Over" screen later on
break;
}
}
}
}
The effect on the game after these changes in GameEngine was absolutely none.
So, it was a successful refactoring ;-)
Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer
Comments
Thanks for this one!
Dude.. it's very hard to get logged in and place a comment here.. I had to sign in twice and reload 5 times. Anyway; thanks for this tutorial. You helped me develop aPpLeZ (check it in the market ;). I also run a blog on android development. I'm not a professional developer. It's in dutch, you might want to check it out @ http://happyworx.nl/blog .
I'll keep reading your posts.. are you planning any new projects in the near future?
Thanks again!
Rgdz., K.
You're welcome ;-)
I know, the site site is hosted on a very shaky connection :-/
I have no actual project ongoing as of now, but I'm sure I will have one during the summer ;-)
BR - Anders