You are here

Chapter 12: Implement the GameThread

Right click on your package, select New -> Class, name it "GameThread" and paste in the following code:

package com.ajomannen.justroids;

import android.content.Context;
import android.graphics.Canvas;
import android.os.Handler;
import android.view.SurfaceHolder;

public class GameThread extends Thread {
  private SurfaceHolder surfaceHolder;
  private Canvas canvas;
  private long delay = 1000000000L / 25;
  private long beforeTime = 0;
  private long afterTime = 0;
  private long timeDiff = 0;
  private long sleepTime;
  private long overSleepTime = 0;
  private long excess = 0;
 
  public final static int RUNNING = 1;
  public final static int PAUSED = 2;
  private static final int MAX_FRAME_SKIPS = 5;
  int state = RUNNING;
 
  GameEngine gameEngine;
 
  public GameThread(SurfaceHolder surfaceHolder, Context context,
    Handler handler, GameEngine gameEngine) {
   this.surfaceHolder = surfaceHolder;
   this.gameEngine = gameEngine;
  }
 
  @Override
  public void run() {
 
   while (state == RUNNING) {
    beforeTime = System.nanoTime();
 
    gameEngine.Update();
 
    canvas = null;
    try {
     canvas = surfaceHolder.lockCanvas(null);
     synchronized (surfaceHolder) {
      gameEngine.Draw(canvas);
     }
    } finally {
     if (canvas != null) {
      surfaceHolder.unlockCanvasAndPost(canvas);
     }
    }
 
    afterTime = System.nanoTime();
    timeDiff = afterTime - beforeTime;
    sleepTime = ((delay) - timeDiff) - overSleepTime;
 
    if (sleepTime > 0) {
     try {
      sleep(sleepTime / 1000000L);
     } catch (InterruptedException ex) {
     }
     overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
    } else {
     excess -= sleepTime;
     overSleepTime = 0L;
    }
 
    int skips = 0;
    while ((excess > delay) && (skips < MAX_FRAME_SKIPS)) {
     excess -= delay;
     gameEngine.Update();
     skips++;
    }
 
   }
 
  }

}

 

An even simpler version of this thread could just call the GameEngine's Update and Draw methods 25 times per second, but since we know for a fact that there are lots of other apps running in the background on a typical device, it is more or less necessary to add timing functionality and skip drawing and just run updates until we are in sync again if necessary.

I will write this game with an update frequency of 25 frames per second. I estimate the maximum number of moving objects in JustRoids to be less than 50 (1 ship, 20 asteroids and 20 missiles) so I reckon that the CPU will be sufficient for this on any kind of Android 2.1 device. (These are of course very rough assumptions, but if it does not work it will be a pretty simple task to half the fps and double the speed of all objects afterwards to compensate.)

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer