This is the CupView Class.
package my.package;
import org.openintents.hardware.SensorManagerSimulator;
import org.openintents.provider.Hardware;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.animation.RotateAnimation;
import android.widget.TextView;
class CupView extends SurfaceView implements SurfaceHolder.Callback{
class CupThread extends Thread{
/**Indicate whether the surface has been created & is read to
draw
*/
private boolean mRun = false;
private SurfaceHolder mSurfaceHolder;
private Handler mHandler;
private int mCanvasHeight = 1;
private int mCanvasWidth = 1;
private int mCupWidth;
private int mCupHeight;
private Drawable mCupImage;
private Bitmap mBgroundImage;
private int mRotation = 0;
private int mMode;
public static final int STATE_RUNNING = 1;
public static final int STATE_PAUSED = 2;
public static final int STATE_NEW = 3;
public static final int STATE_SHAKING = 4;
/** The state of the game. One of RUNNING, NEW, SHAKING or
PAUSED */
//-----------------------------------------------------------------------------------------
public CupThread(SurfaceHolder surfaceHolder, Context context,
Handler handler){
// get handles to some important objects
mSurfaceHolder = surfaceHolder;
mHandler = handler;
mContext = context;
mCupImage =
mContext.getResources().getDrawable(R.drawable.cup);
mCupImage.setFilterBitmap(true);
mBgroundImage = BitmapFactory.decodeResource
(context.getResources(),
R.drawable.background_vert);
//setState(STATE_SHAKING);
}
//-----------------------------------------------------------------------------------------
public void run(){
while (mRun){
Canvas c = null;
try{
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder){
doDraw(c);
}
}finally{
// do this in a finally so that if an
exception is thrown in the
above,
// we don't leave the Surface in an
inconsistent state
if (c != null){
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
//-----------------------------------------------------------------------------------------
/* Used to signal the thread whether it should be running or
not.
Passing true allows the
* thread to run; passing false will shut it down if it's
already
running. Calling start()
* after this was most recently called with false will result
in an
immediate shutdown.
*/
public void setRunning (boolean b){
mRun = b;
}
//-----------------------------------------------------------------------------------------
/* Callback invoked when the surface dimensions change. */
public void setSurfaceSize(int w, int h){
// synchronized to make sure these all change atomically
synchronized (mSurfaceHolder){
mCanvasWidth = w;
mCanvasHeight = h;
}
}
//-----------------------------------------------------------------------------------------
/* Draws the cup to the provided canvas */
private void doDraw(Canvas canvas){
canvas.drawBitmap(mBgroundImage,0,0,null);
canvas.save();
if (mMode == STATE_SHAKING){
if (mRotation==0){
canvas.rotate(3,
mCupImage.getIntrinsicWidth()/2,
mCupImage.getIntrinsicHeight()/2);
mRotation=1;
}else{
canvas.rotate(-3,
mCupImage.getIntrinsicWidth()/2,
mCupImage.getIntrinsicHeight()/2);
mRotation=0;
}
}
mCupImage.setBounds(getLeft(), getTop(), getRight(),
getBottom());
mCupImage.draw(canvas);
canvas.restore();
}
//-----------------------------------------------------------------------------------------
public void pause() {
synchronized (mSurfaceHolder) {
setState(STATE_PAUSED);
}
}
//---------------------------------------------------------------------
public void unpause() {
setState(STATE_RUNNING);
}
//-----------------------------------------------------------------------------------------
public void setState(int mode){
synchronized (mSurfaceHolder){
mMode = mode;
}
}
}
//---------------------------------------------------------------------------------------------
/** Handle ot the application context, used to e.g. fetch Drawables.
*/
private Context mContext;
/** The thread that actually draws teh animations. */
private CupThread thread;
private TextView mStatusText;
public CupView(Context context, AttributeSet attrs){
super(context,attrs);
//register our interest in hearing about changes to our surface
SurfaceHolder holder = getHolder();
holder.addCallback(this);
mContext = context;
setFocusable(true);
// create thread only; it's started in surfaceCreated()
}
//---------------------------------------------------------------------------------------------
public CupThread getThread(){
return thread;
}
//---------------------------------------------------------------------------------------------
/**
* Installs a pointer to the text view used for messages.
*/
public void setTextView(TextView textView) {
mStatusText = textView;
}
//---------------------------------------------------------------------------------------------
/* Callback invoked when the Surface dimensions change. */
public void surfaceChanged(SurfaceHolder holder, int format, int
width, int height){
thread.setSurfaceSize(width,height);
}
//---------------------------------------------------------------------------------------------
/* Callback invoked when the Surface has been created and is read to
be used. */
public void surfaceCreated(SurfaceHolder holder){
// start the thread here so that we don't busy-wait in run()
// waiting for the surface to be created
Log.d("MyApp","cup view surface created");
thread = new CupThread(holder, mContext, new Handler() {
@Override
public void handleMessage(Message m) {
mStatusText.setVisibility(m.getData().getInt("viz"));
mStatusText.setText(m.getData().getString("text"));
}
});
thread.setRunning(true);
thread.start();
}
//---------------------------------------------------------------------------------------------
/* Callback invoked when the Surface has been destroyed and must no
longer be touched.
* WARNING: after this method returns, the Surface/Canvas must never
be touched again!
* (Unless its REALLY asking for it.)
*/
public void surfaceDestroyed(SurfaceHolder holder){
// we have to tell thread to shut down & wait for it to finish,
or
else it might touch
// the Surface(wouldn't want that!) after we return and explode
(ahhh!).
Log.d("MyApp","cup view surface destroyed");
boolean retry = true;
thread.setRunning(false);
while (retry){
try{
thread.join();
retry = false;
}catch(InterruptedException e){
}
}
}
}
On Mar 31, 10:41 pm, kbeal10 <[email protected]> wrote:
> This is the main Activity of my app. The one holding a CupView.
>
> package my.package;
>
> import my.package.CupView.CupThread;
> import org.openintents.hardware.SensorManagerSimulator;
> import org.openintents.provider.Hardware;
>
> import android.app.Activity;
> import android.content.Intent;
> import android.hardware.SensorListener;
> import android.hardware.SensorManager;
> import android.os.Bundle;
> import android.util.Log;
> import android.view.Menu;
> import android.view.MenuItem;
> import android.view.View;
> import android.widget.Button;
> import android.widget.TextView;
>
> public class MyActivity extends Activity {
>
> private static final int MENU_NEWGAME = 1;
> private static final int MENU_RESUMEGAME = 2;
> private static final int MENU_EXITGAME = 3;
> private static final int ROLL_DICE_ACTIVITY = 1;
> /** The modes the game can be in **/
> private static final int ENTER = 1; // just entered the game
> private static final int IN_PROGRESS = 2; // less than 13 turns
> private static final int GAME_OVER = 3; // 13 turns has been reached
> private int mMode;
> private int mTurnCount;
> private int mHeldDiceCount;
> private String mName;
> private CupView mCupView;
> private Button mScoreButton;
> private Button mRollButton;
> private int mRollCount;
> public static ScoresDbAdapter mDbHelper;
> private CupThread mCupThread;
> private long mGameID;
> TextView mInstruct;
> private SensorManager mSensorManager;
> private float mLastX;
> private SensorListener mAccellListener;
> private int mShake;
> private boolean mShaking;
>
> /** Called when the activity is first created. */
> public void onCreate(Bundle savedInstanceState) {
> super.onCreate(savedInstanceState);
> // set the content view to the main game board (the cup)
> setContentView(R.layout.board);
> if (savedInstanceState == null){
> setState(ENTER);
> mHeldDiceCount = 0;
> mRollCount = 0;
> }else{
> setState(IN_PROGRESS);
> }
>
> mInstruct = (TextView) findViewById(R.id.top_text);
>
> //get the cup view
> mCupView = (CupView) findViewById(R.id.cup);
> mCupThread = mCupView.getThread();
>
> // Before calling any of the Simulator data,
> // the Content resolver has to be set !!
> Hardware.mContentResolver = getContentResolver();
>
> // Link sensor manager to OpenIntents Sensor simulator
> mSensorManager =
> (SensorManager) new SensorManagerSimulator((SensorManager)
> getSystemService(SENSOR_SERVICE));
>
> //setUpAccell();
>
> // give the LunarView a handle to the TextView used for
> messages
> mCupView.setTextView((TextView) findViewById(R.id.text));
>
> // get the score sheet button and set its listener
> mScoreButton = (Button) findViewById(R.id.score_button);
> mScoreButton.setOnClickListener(new Button.OnClickListener() {
> public void onClick(View v){
> openScoreSheet();
> }
> });
>
> mRollButton = (Button) findViewById(R.id.roll_button);
> mRollButton.setOnClickListener(new Button.OnClickListener() {
> public void onClick(View v){
> rollDice();
> }
> });
> mDbHelper = new ScoresDbAdapter(this);
> mDbHelper.open();
>
> }
>
> //-------------------------------------------------------------------------
> private void openScoreSheet(){
> if (mMode==IN_PROGRESS){
> Intent i = new Intent(this, ScoreSheet.class);
> i.putExtra("my.package.GameID", mGameID);
> startActivity(i);
> }
> }
>
> //-------------------------------------------------------------------------
> public boolean onCreateOptionsMenu(Menu menu){
> super.onCreateOptionsMenu(menu);
>
> menu.add(0,MENU_NEWGAME,0,R.string.menu_newgame);
> menu.add(0,MENU_RESUMEGAME,0,R.string.menu_resumegame);
> menu.add(0,MENU_EXITGAME,0,R.string.menu_exitgame);
>
> return true;
> }
>
> //-------------------------------------------------------------------------
> public boolean onOptionsItemSelected(MenuItem item){
> switch (item.getItemId()){
> case MENU_NEWGAME:
> createNewGame();
> return true;
> case MENU_RESUMEGAME:
> resumeGame();
> return true;
> case MENU_EXITGAME:
> return true;
> }
> return false;
> }
>
> //-------------------------------------------------------------------------
> /**
> * My own listener interface to use for getting values back from a
> dialog.
> */
> public interface CreateGameListener{
> public void onOKClick(String name);
> public void onCancelClick();
> }
>
> //-------------------------------------------------------------------------
> /**
> * Method called from CreateGameListener's onOKClick
> */
> public void okClick(String n, long game){
> mName = n;
> // TextView topText = (TextView) findViewById(R.id.top_text);
> // Long gameInt = new Long(game);
> // topText.setText(gameInt.toString());
> mGameID = mDbHelper.createGame(n);
> }
>
> //-------------------------------------------------------------------------
> private void createNewGame(){
> mRollCount = 0;
> mTurnCount = 0;
> setState(IN_PROGRESS);
> // start the activity that asks for the name of the new game
> CreateGameListener listener = new CreateGameListener(){
> public void onOKClick(String n){
> okClick(n,mGameID);
> }
> public void onCancelClick(){
>
> }
> };
> CreateGame dialog = new CreateGame(mCupView.getContext
> (),listener);
> dialog.show();
> }
>
> //-------------------------------------------------------------------------
> private void resumeGame(){
> setState(IN_PROGRESS);
> // create a new intent that has a list of all the games
> Intent i = new Intent(this,ResumeGameList.class);
> startActivity(i);
> }
>
> //-------------------------------------------------------------------------
> private void rollDice(){
> if (mMode==IN_PROGRESS){
> // create a new intent for the roll dice view
> Intent i = new Intent(this,RollDice.class);
> mRollCount = mRollCount + 1;
> if (mRollCount == 3){
> mTurnCount += 1;
> }
> if (mTurnCount == 13){
> setState(GAME_OVER);
> }
> i.putExtra("my.package.RollCount", mRollCount);
> i.putExtra("my.package.GameID",mGameID);
> startActivityForResult(i,ROLL_DICE_ACTIVITY);
> // startActivity(i);
> // finish();
> }
> }
>
> //-------------------------------------------------------------------------
> @Override
> protected void onActivityResult(int requestCode, int resultCode,
> Intent data) {
> super.onActivityResult(requestCode, resultCode, data);
> if (requestCode == 1){
> // if its returning after the third role
> if (resultCode == RollDice.READY_TO_SCORE){
> // start the ChooseScore Activity.
> mRollCount = 0;
> startActivity(data);
> }else{
> mHeldDiceCount = resultCode;
> }
> }
> }
>
> //-------------------------------------------------------------------------
> public void setState(int mode){
> if (mode == ENTER){
> //mInstruct.setText("Press Menu to start a game.");
> }
> if (mode == IN_PROGRESS){
> //mInstruct.setText("Shake phone to shake dice.");
> }
> if (mode == GAME_OVER){
> //mInstruct.setText("Game Over");
> }
> mMode = mode;
> }
>
> //-------------------------------------------------------------------------
> public int getState(){return mMode;}
>
>
> //-------------------------------------------------------------------------
> protected void onPause(){
> super.onPause();
> }
> //
> //-------------------------------------------------------------------------
> protected void onResume(){
> super.onResume();
> }
>
> //-------------------------------------------------------------------------
> public void setUpAccell(){
> mLastX = 0;
> mShake = 0;
> mAccellListener = new SensorListener() {
> Float x;
> public void onSensorChanged(int sensor, float[] values){
> if (sensor == SensorManager.SENSOR_ACCELEROMETER){
> x = values[SensorManager.DATA_X];
>
> if ((x-mLastX>.5)||(x-mLastX<-.5)){
> mShake += 1;
> }
> // if
> (((x-mLastX<.5)||(x-mLastX>-.5))&&(mShake>=0)){
> // mShake -= 1;
> // }
>
> if (mShake>3){
> mShaking = true;
>
> mCupThread.setState(mCupThread.STATE_SHAKING);
> }
> if (mShake==0&&mShaking){
> mShaking = false;
>
> mCupThread.setState(mCupThread.STATE_RUNNING);
> }
> mLastX = x;
> }
> }
> public void onAccuracyChanged(int sensor, int acc){}
> };
>
> // now connect to simulator
> SensorManagerSimulator.connectSimulator();
>
> // now enable the new sensors
> mSensorManager.registerListener(mAccellListener,
> SensorManager.SENSOR_ACCELEROMETER);
> }
>
> }
>
> On Mar 31, 10:35 pm, kbeal10 <[email protected]> wrote:
>
> > This is where the thread variable is declared.
>
> > private Context mContext;
> > /** The thread that actually draws teh animations. */
> > private CupThread thread;
> > private TextView mStatusText;
>
> > public CupView(Context context, AttributeSet attrs){
> > super(context,attrs);
>
> > //register our interest in hearing about changes to our
> > surface
> > SurfaceHolder holder = getHolder();
> > holder.addCallback(this);
> > mContext = context;
> > setFocusable(true);
> > // create thread only; it's started in surfaceCreated()
> > }
>
> > I'm sorry for the confusion about "exiting" in rollDice().
>
> ...
>
> read more »
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---