GameActivity.java :  » Game » andforge-game-development-tutorial-client » com » andlabs » gd » base » Android Open Source

Android Open Source » Game » andforge game development tutorial client 
andforge game development tutorial client » com » andlabs » gd » base » GameActivity.java
package com.andlabs.gd.base;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;

import com.andlabs.gd.R;

public abstract class GameActivity extends Activity implements OnTouchListener, SensorEventListener, SurfaceHolder.Callback {

  /**
   * the game's (surface)view
   */
  private SurfaceView mGameView;
  /**
   * determines whether the main game loop is running or not
   */
  private boolean mMainLoopRunning;
  /**
   * the surface holder of the game view
   */
  private SurfaceHolder mSurfaceHolder;
  /**
   * the main game rendering thread
   */
  private Thread mRenderingThread;
  /**
   * the main game simulation thread
   */
  private Thread mSimulationThread;
  /**
   * listener for the game's simulation
   */
  private SimulationListener mSimulationListener;
  /**
   * listener for the game's rendering
   */
  private RenderingListener mRenderingListener;
  
  /**
   * the delta time between the last simulation iteration and now
   */
  private float mDeltaTime = 0;
  /**
   * the timestamp of the last simulation iteration
   */
  private long mLastSimulationIteration = 0;  
  /** 
   * touch coordinates
   **/
    private int mTouchX, mTouchY;
    /**
     * touched state
     */
    private boolean mIsTouched;
    /**
     * acceleration on the 3 axis 
     **/
    private float[] mAcceleration = new float[3];    
    /**
     * all these are for calculating the fps
     */
    private int mFPS = 0;
    private int mFPSCount = 0;
    private float mTimeElapsed = 0;
    private long mLastRenderingIteration = 0;
  public boolean mIsMoving;
  
  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        mGameView = new SurfaceView(this);
        mSurfaceHolder = mGameView.getHolder();
        mSurfaceHolder.addCallback(this);
        mGameView.setOnTouchListener(this);
        setContentView(mGameView);        
     
        mMainLoopRunning = true;
                
        mRenderingThread = new Thread(new Runnable(){
          public void run() {
            render();
          }
        }, "Rendering Thread");        
        
        mSimulationThread = new Thread(new Runnable(){
          public void run() {          
            simulate();
          }
        }, "Simulation Thread");
        
        SensorManager manager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        if(manager.getSensorList(Sensor.TYPE_ACCELEROMETER).size() > 0){
          final Sensor accelerometer = manager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
            manager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME );
        }
    }  
  
  @Override
  public boolean onTouch(View v, MotionEvent event) {
     if(event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE){
           mTouchX = (int)event.getX();
           mTouchY = (int)event.getY();
           mIsTouched = true;
           
           if(event.getAction() == MotionEvent.ACTION_MOVE){
             mIsMoving = true;
           }
       }

        if( event.getAction() == MotionEvent.ACTION_UP ){
             mIsTouched = false;
             mIsMoving = false;
        }

        try{
             Thread.sleep( 30 );
        }catch(Exception ex){
          //zonk!
        } 
        
        return true;
  }
  
  private void render(){
    if(mRenderingListener != null){
      mRenderingListener.initializeSplash();
    }
    new Thread(new Runnable(){
      @Override
      public void run() {
            if(mRenderingListener != null){
              mRenderingListener.initializeRendering();
            }                
      }
    }).start();
    Canvas c;
    while(mMainLoopRunning){
      c = null;
          try {
            c = mSurfaceHolder.lockCanvas();
              synchronized (mSurfaceHolder) {
                if(mRenderingListener != null){
                  if(mRenderingListener.isInitializingRendering() || mSimulationListener == null || mSimulationListener.isInitializingSimulation()){
                    mRenderingListener.renderSplash(c);
                  } else{
                    mRenderingListener.render(c);
                  }
                }
              }
          } finally {
              // do this in a finally so that if an exception is thrown
              // during the above, we don't leave the Surface in an
              // inconsistent state
              if (c != null) {
                  mSurfaceHolder.unlockCanvasAndPost(c);
              }
          }                
      
          //the fps calculation
      mFPSCount++;
      mTimeElapsed += (System.nanoTime() - mLastRenderingIteration) / 1000000000.0;      
      if(mTimeElapsed >= 1){
        mFPS = mFPSCount;
        Log.d("GameActivity", "FPS: " + mFPS);
        mFPSCount = 0;
        mTimeElapsed = 0;
      }      
      mLastRenderingIteration = System.nanoTime();
    }
  }
  
  private void simulate(){
    
    if(mSimulationListener != null){
          mSimulationListener.initializeSimulation();
    }
        
    while(mMainLoopRunning){
      if(mSimulationListener != null && !mSimulationListener.isInitializingSimulation() && mRenderingListener != null && !mRenderingListener.isInitializingRendering()){
        mDeltaTime = (System.nanoTime() - mLastSimulationIteration) / 1000000000.0f;
        mLastSimulationIteration = System.nanoTime();
        mSimulationListener.simulationIteration(mDeltaTime);       
      }
    }
  }
  
  public void startIterations(){
    mMainLoopRunning = true;
    mRenderingThread.start();
        mSimulationThread.start();     
  }
  
  public void stopIterations(){
    mMainLoopRunning = false;
    boolean retry = true;
    //stop the rendering thread
    while (retry) {
      try {
            mRenderingThread.join();
              retry = false;
          } catch (InterruptedException e) {
              // we will try it again and again...
          }
      }
    
    //stop the simulation thread
    retry = true;
    while (retry) {
      try {
            mSimulationThread.join();
              retry = false;
          } catch (InterruptedException e) {
              // ...
          }
      }
  }

  public void setSimulationListener(SimulationListener simulationListener) {
    mSimulationListener = simulationListener;
  }

  public void setRenderingListener(RenderingListener renderingListener) {
    mRenderingListener = renderingListener;
  }
  
  /**
   * @return the frames per second
   */
  public int getFPS(){
    return mFPS;
  }
  
  /** 
   * Called when the accuracy of the Sensor has changed.
   * @param sensor
   * @param accuracy
   */
  @Override
  public void onAccuracyChanged(Sensor sensor, int accuracy){
          // we ignore this
  }

  /**
   * Called when the sensor has new input
   * @param event The SensorEvent
   */
  @Override
  public void onSensorChanged(SensorEvent event){
          System.arraycopy( event.values, 0, mAcceleration, 0, 3 );
  }
  
  /**
   * @return the delta time in seconds
   */
  public float getDeltaTime( ){
          return mDeltaTime;
  }

  /**
   * @return the last known touch coordinate on the x axis
   */
  public int getTouchX( ){
          return mTouchX;
  }

  /**
   * @return the last known touch coordinate on the x axis
   */
  public int getTouchY( )  {
          return mTouchY;
  }

  /**
   * @return whether the touch screen is touched or not
   */
  public boolean isTouched( )  {
          return mIsTouched;
  }

  /**
   * @return the acceleration on the x-Axis of the device
   */
  public float getAccelerationOnXAxis( ){
          return mAcceleration[0];
  }

  /**
   * @return the acceleration on the x-Axis of the device
   */
  public float getAccelerationOnYAxis( ){
          return mAcceleration[1];
  }

  /**
   * @return the acceleration on the x-Axis of the device
   */
  public float getAccelerationOnZAxis( ){
          return mAcceleration[2];
  }
  
  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width,
      int height) {
    //implement something, if this can happen in your game 
  }

  /**
   * called when the surface created
   */
  @Override
  public void surfaceCreated(SurfaceHolder holder) {
    //start the two main threads
    startIterations();
  }

  /**
   * called when the surface is destroyed
   */
  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {
    //stop the two main threads
    stopIterations();
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.