GameProc.java :  » Game » rogue-op » rogue_opcode » Android Open Source

Android Open Source » Game » rogue op 
rogue op » rogue_opcode » GameProc.java
// GameProc.java
// Game main logic class
//
// Copyright 2010 Brigham Toskin
// This software is part of the Rogue-Opcode game framework. It is distributable
// under the terms of a modified MIT License. You should have received a copy of
// the license in the file LICENSE. If not, see:
// <http://code.google.com/p/rogue-op/wiki/LICENSE>
//
// Formatting:
// 80 cols ; tabwidth 4
// //////////////////////////////////////////////////////////////////////////////


package rogue_opcode;


import rogue_opcode.geometrics.XYf;
import rogue_opcode.soundy.SoundEffect;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;


public class GameProc extends Activity implements Runnable, OnGestureListener,
    OnDoubleTapListener
{
  public static final long UPDATE_FREQ = 30;
  public static final long UPDATE_PERIOD = 1000 / UPDATE_FREQ;
  public static final String TAG = "ionoclast";

  public static GameProc sOnly;
  protected static Thread sUpdateThread;

  // stats
  protected long mElapsedTime;
  protected static int sSeconds;
  protected static long sFPS;

  protected boolean mMousing;
  protected XYf mMousePos;

  private GestureDetector detector;
  public TouchState mTouchState;

  int mCurrentKey;
  public boolean[] mKeys; //holds the state of the keys on the keyboard


  protected boolean mRunning;
  protected boolean mRestarting;
  protected boolean mExiting;

  // app lifecycle ///////////////////////////////////////////////////////////

  /** Called when the activity is first created. */
  @Override
  protected void onCreate(Bundle savedState)
  {
    Log.d(TAG, "onCreate()");
    super.onCreate(savedState);
    sOnly = this;

    mKeys = new boolean[525];

    // set up graphics
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    Window tWin = getWindow();
    tWin.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    tWin.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);

    new AnimatedView(this);

    // initialize stats
    mElapsedTime = 0;
    sSeconds = 0;
    sFPS = 0;

    //    if(savedState != null)
    //    {
    //      Log.d(TAG, "  Restoring state");
    //      super.onRestoreInstanceState(savedState);
    //      ActionElement.sAllAEs = (Array<ActionElement>)savedState
    //          .getSerializable("sAllAEs");
    //      AudioResource.sAllARs = (HashMap<Integer, AudioResource>)savedState
    //          .getSerializable("sAllARs");
    //    }

    // user-provided init code
    detector = new GestureDetector(this, this);
    mTouchState = new TouchState();

    InitializeOnce();
  }

  @Override
  public void onSaveInstanceState(Bundle outState)
  {
    Log.d(TAG, "onSaveInstanceState()");
    super.onSaveInstanceState(outState);
    //      outState.putSerializable("sAllAEs", ActionElement.sAllAEs);
    //      outState.putSerializable("sAllARs", AudioResource.sAllARs);
  }

  /**
   * Called when app becomes active.
   */
  @Override
  protected void onResume()
  {
    Log.d(TAG, "onResume()");
    super.onResume();

    // input data
    mMousing = false;
    mMousePos = new XYf();

    // restore user settings
    SharedPreferences tPrefs = getPreferences(0);
    if(tPrefs.getBoolean("saved", false))
    {
      // TODO: restore settings to SettingsDB object in loop
    }
    else
    {
      // TODO: load SettingsDB with default values
    }

    Log.d(TAG, "  creating static arrays");
    ActionElement.Init();
    ScreenElement.Init();
    SoundEffect.Init();

    // user initialization code
    InitializeOnResume();

    // start the render and update threads
    (sUpdateThread = new Thread(this)).start();
    (AnimatedView.sRenderThread = new Thread(AnimatedView.sOnly)).start();

    AnimatedView.sOnly.requestFocus();


    // clean some up now to avoid latency later
    Runtime r = Runtime.getRuntime();
    r.gc();
  }

  /** Called when app is backgrounded, but may still be visible. */
  @Override
  protected void onPause()
  {
    Log.d(TAG, "onPause()");
    super.onPause();

    Shutdown();

    // save user settings
    SharedPreferences.Editor tEditor = getPreferences(0).edit();
    // TODO: save user settings in a loop from a static SettingsDB;
    // each entry is { "name", setting_type, setting_data }.
    tEditor.putBoolean("saved", true);
    tEditor.commit();

    // shut down
    Die();
    AnimatedView.sOnly.Die();
    AudioResource.Die(); // stop and free all audio resources
    SoundEffect.Die(); // free the sound pool

    // clean some up now to avoid latency later
    Runtime r = Runtime.getRuntime();
    r.gc();
  }

  //  /** Called on app shutdown. */
  //@Override
  /*
   * protected void onDestroy()
   * {
   * Log.d(TAG, "onDestroy()");
   * super.onDestroy();
   * 
   * Shutdown();
   * }
   */

  /** Stops the update thread. */
  void Die()
  {
    synchronized(this)
    {
      mRunning = false;
      sUpdateThread = null;
    }
  }

  /** Override this in your derived class to make stuff. */
  public void InitializeOnce()
  {
  }

  /** Override this to hook the resume event. */
  public void InitializeOnResume()
  {
  }

  /** Override this to hook the shutdown event. */
  public void Shutdown()
  {
  }

  // game update loop ////////////////////////////////////////////////////////

  /** Thread to run logic updates */
  @Override
  public void run()
  {
    Log.d(TAG, "Entering update thread");
    mRunning = true;
    while(mRunning)
    {
      long start = SystemClock.uptimeMillis();

      // calc stats
      if(mElapsedTime >= 999)
      {
        synchronized(this)
        {
          sSeconds++;
          mElapsedTime -= 1000;
          sFPS = AnimatedView.sOnly.FPS();
        }
      }

      Update();

      long end = SystemClock.uptimeMillis();
      long tLastUpdate = end - start;
      mElapsedTime += UPDATE_PERIOD;
      try
      {
        long tSleep = UPDATE_PERIOD - tLastUpdate;
        if(tSleep < 1)
          tSleep = 1;
        Thread.sleep(tSleep);
      }
      catch(InterruptedException e)
      {
      }
    }
    Log.d(TAG, "Exiting update thread");
  }

  // public interfaces //

  /** Calls update on all extant ActionElements. */
  public void Update()
  {
    for(int i = 0; i < ActionElement.sAllAEs.size; i++)
    {
      try
      {
        ActionElement tAE = ActionElement.sAllAEs.At(i);
        if(tAE.Active())
          tAE.Update();
      }
      catch(Exception e)
      {
      }
    }
    
    mTouchState.Clear();
  }

  // runtime stats ///////////////////////////////////////////////////////////

  /** Query performance statistics based on update timing. */
  // TODO: does this belong here? Move to AnimatedView
  long FPS()
  {
    synchronized(this)
    {
      return sFPS;
    }
  }

  /** Query uptime statistics for update thread. */
  long Seconds()
  {
    synchronized(this)
    {
      return sSeconds;
    }
  }

  // user input callbacks ////////////////////////////////////////////////////

  @Override
  public boolean onTrackballEvent(MotionEvent pEvent)
  {
    mMousePos.x = (int)(pEvent.getX() * 100);
    mMousePos.y = (int)(pEvent.getY() * 100);

    mMousing = true;
    return true;
  }

  public boolean Mousing()
  {
    return mMousing;
  }

  public XYf MousePos()
  {
    mMousing = false;
    return mMousePos;
  }


  @Override
  public boolean onTouchEvent(MotionEvent me)
  {
    this.detector.onTouchEvent(me);
    return super.onTouchEvent(me);
  }

  @Override
  public boolean onDown(MotionEvent e)
  {
    //Toast.makeText(GameProc.sOnly, "down", 0).show();
    return false;
  }

  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
      float velocityY)
  {
    mTouchState.SetState(TouchState.FLING, e1, e2);
    return false;
  }

  @Override
  public void onLongPress(MotionEvent e)
  {
    mTouchState.SetState(TouchState.LONG_TOUCH, e, null);
  }

  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
      float distanceY)
  {
    //Toast.makeText(GameProc.sOnly, "scroll", 0).show();
    return false;
  }

  @Override
  public void onShowPress(MotionEvent e)
  {
    //Toast.makeText(GameProc.sOnly, "show press", 0).show();
  }

  @Override
  public boolean onSingleTapUp(MotionEvent e)
  {
    //Toast.makeText(GameProc.sOnly, "single tap up", 0).show();
    return false;
  }

  @Override
  public boolean onDoubleTap(MotionEvent e)
  {
    mTouchState.SetState(TouchState.DOUBLE_TAP, e, null);
    return false;
  }

  @Override
  public boolean onDoubleTapEvent(MotionEvent e)
  {
    //Toast.makeText(GameProc.sOnly, "double tap event", 0).show();
    return false;
  }

  @Override
  public boolean onSingleTapConfirmed(MotionEvent e)
  {
    mTouchState.SetState(TouchState.SINGLE_TAP, e, null);
    return false;
  }


  /**
   * TouchState is an inner class that holds state information about touch
   * events.
   * It is designed to be polled instead of event-driven.
   * 
   * @author Christopher R. Tooley
   * 
   */
  protected class TouchState
  {
    public static final int SINGLE_TAP = 1;
    public static final int DOUBLE_TAP = 2;
    public static final int FLING = 4;
    public static final int SCROLL = 8;
    public static final int LONG_TOUCH = 16;

    int mState;

    MotionEvent mMainMotionEvent;
    MotionEvent mSecondaryMotionEvent;

    TouchState()
    {
      Clear();
    }

    public void SetState(int pState, MotionEvent pMainMotionEvent,
        MotionEvent pSecondaryMotionEvent)
    {
      synchronized(this)
      {
        mState |= pState;
        mMainMotionEvent = pMainMotionEvent;
        mSecondaryMotionEvent = pSecondaryMotionEvent;
      }
    }

    public void Clear()
    {
      synchronized(this)
      {
        mState = 0;
      }
    }

    public XYf TouchPos() {
      return new XYf(mMainMotionEvent.getX(), mMainMotionEvent.getY());
    }
    
    public XYf SecondaryTouchPos() {
      return new XYf(mSecondaryMotionEvent.getX(), mSecondaryMotionEvent.getY());
    }
    
    public float GetMainX()
    {
      float tX = 0;
      synchronized(this)
      {
        tX = mMainMotionEvent.getX();
      }
      return tX;
    }

    public float GetMainY()
    {
      float tY = 0;
      synchronized(this)
      {
        tY = mMainMotionEvent.getY();
      }
      return tY;
    }

    public float GetSecondaryX()
    {
      float tX = 0;
      synchronized(this)
      {
        tX = mSecondaryMotionEvent.getX();
      }
      return tX;
    }

    public float GetSecondaryY()
    {
      float tY = 0;
      synchronized(this)
      {
        tY = mSecondaryMotionEvent.getY();
      }
      return tY;
    }

    public boolean Is(int pState)
    {
      synchronized(this)
      {
        return 0 != (mTouchState.mState & pState);
      }
    }
  }

}
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.