Creating a sample game loop using the Android SDK

Android SDK development starts with an activity, and the game runs on single or multiple views. Most of the time, it is considered to have a single view to run gameplay.

Unfortunately, the Android SDK does not provide a predefined game loop. However, the loop can be created in many ways, but the basic mechanism remains the same.

In the Android SDK library, the View class contains an abstract method OnDraw() in which every possible rendering call is queued. This method is called upon any change in the drawing, which invalidates the previous rendering pipeline.

The logic is as follows:

Creating a sample game loop using the Android SDK

Let's have a look at a basic game loop created with Android View. Here, a custom view is extended from the Android View:

/*Sample Loop created within OnDraw()on Canvas 
* This loop works with 2D android game development
*/
@Override
public void onDraw(Canvas canvas)
{
  //If the game loop is active then only update and render
  if(gameRunning)
  {
    //update game state
    MainGameUpdate();

    //set rendering pipeline for updated game state
    RenderFrame(canvas);
    //Invalidate previous frame, so that updated pipeline can be
    // rendered
    //Calling invalidate() causes recall of onDraw()
    invalidate();
  }
  else
  {
    //If there is no active game loop
    //Exit the game
    System.exit(0);
  }
}

In the current age of Android game development, developers use SurfaceView instead of View. SurfaceView is inherited from View and more optimized for games made with Canvas. In this case, a customized view is extended from SurfaceView and implements the SurfaceHolder.Callback interface. In this scenario, three methods are overridden:

/* Called When a surface is changed */
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
}
/* Called on create of a SurfaceView */
@Override
public void surfaceCreated(SurfaceHolder holder)
{
}
/* Called on destroy of a SurfaceView is destroyed */
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
}

While developing a game, the developer need not change the surface each time. That's the reason the surfaceChanged method should have an empty body to function as a basic game loop.

We need to create a customized game thread and override the run() method:

public class BaseGameThread extends Thread
{
  private boolean isGameRunning;
  private SurfaceHolder currentHolder;
  private MyGameState currentState;
  public void activateGameThread(SurfaceHolder holder, MyGameState state)
  {
    currentState = state;
    isGameRunning = true;
    currentHolder = holder;
    this.start();
  }

  @Override
  public void run()
  {
    Canvas gameCanvas = null;
    while(isGameRunning)
    {
      //clear canvas
      gameCanvas = null;
      try
      {
        //locking the canvas for screen pixel editing
        gameCanvas  = currentHolder.lockCanvas();
        //Update game state
        currentState.update();
        //render game state
        currentState.render(gameCanvas);
      }
      catch(Exception e)
      {
        //Update game state without rendering (Optional)
        currentState.update();
      }
    }
  }
}

Now, we are set to start the newly created game loop from the customized SurfaceView class:

public myGameCanvas extends SurfaceView implements SurfaceHolder
{
  //Declare thread
  private BaseGameThread gameThread;
  private MyGameState gameState;
  @Override
  public void surfaceCreated(SurfaceHolder holder)
  {
    //Initialize game state
    gameState = new MyGameState();
    //Instantiate game thread
    gameThread = new BaseGameThread();
    //Start game thread
    gameThread. activateGameThread(this.getHolder(),gameState);
  }

  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
  {
  }

  @Override
  public void surfaceDestroyed(SurfaceHolder holder)
{
}
}

There can be many approaches to implementing a game loop. However, the basic approach follows either of the two ways mentioned here. Some developers prefer to implement the game thread inside the game view. Handling input is another important part of the game loop. We will discuss this topic later in this chapter.

Another part of this game loop is frames per second (FPS) management. One of the most common mechanisms is to use Thread.sleep() for such a calculated time that the loop executes at a fixed rate. Some developers create two types of update mechanism: one based on FPS and another based on per frame without delay.

Mostly, physics-based games need an update mechanism that follows a real-time interval to function uniformly across all devices.

For small-scale development, few developers in the industry follow the first approach but do not follow typical looping. This system invalidates the current draw based on the required action. In this scenario, the game loop is not dependent on fixed FPS.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.182.73