package template.Game;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Bitmap.Config;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class Demoview extends SurfaceView implements SurfaceHolder.Callback {
private boolean[] keys;
/*Keys code :*/
private static final int UP = 0;
private static final int DOWN = 1;
private static final int LEFT = 2;
private static final int RIGHT = 3;
public DemoThread thread;
enum direction {UP,DOWN};
public class DemoThread extends Thread {
protected static final int GUIUPDATEIDENTIFIER = 0x231;
/*
* State-tracking constants
*/
public static final int STATE_LOSE = 1;
public static final int STATE_PAUSE = 2;
public static final int STATE_READY = 3;
public static final int STATE_RUNNING = 4;
public static final int STATE_WIN = 5;
public static final int PHYS_SLEW_SEC = 120;
private static final int SIZE_BALL = 0;
private static final int SIZE = 15;
private SurfaceHolder mSurfaceHolder;
Paint paint;
/*Bitmap for drawing :*/
private Bitmap BitmapTop;
/*Canvas*/
private Canvas canvasTop;
/*Time*/
private long mLastTime=0;
private long now;
private long elapsed;
/*screensize*/
private int W,H;
/*GameMode*/
private int mMode=STATE_RUNNING;
private boolean mRun=false;
/*ball's position*/
Point ballPosition;
/*Ball direction*/
direction dir;
private boolean update=false;
public DemoThread(SurfaceHolder surfaceHolder, Context context) {
mSurfaceHolder = surfaceHolder;
// arbitrary :
W=100;H=100;
BitmapTop = Bitmap.createBitmap(W, H, Config.ARGB_4444);
// init paint :
paint = new Paint();
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
// assign the canvas to a specific bitmap
canvasTop= new Canvas();
canvasTop.setBitmap(BitmapTop);
}
public void setRunning(boolean b) {
mRun = b;
if(mRun) {
Log.d("state","dostart");
doStart();
}
}
/**
* Sets the game mode. That is, whether we are running, paused, in the
* failure state, in the victory state, etc.
*
*/
public void setState(int mode) {
synchronized (mSurfaceHolder) {
mMode=mode;
}
}
/* Callback invoked when the surface dimensions change. */
public void setSurfaceSize(int width, int height) {
// synchronized to make sure these all change atomically
synchronized (mSurfaceHolder) {
W = width;
H = height;
BitmapTop = Bitmap.createBitmap(W, H, Config.ARGB_4444);
canvasTop.setBitmap(BitmapTop);
}
}
public void doStart() {
// init the ball position :
ballPosition=new Point(W/2,H/2);
// init direction :
dir=direction.DOWN;
mLastTime = System.currentTimeMillis() + 100;
setState(STATE_RUNNING);
}
/**
* Resumes from a pause.
*/
public void unpause() {
// Move the real time clock up to now
synchronized (mSurfaceHolder) {
// Move the real time clock up to now
synchronized (mSurfaceHolder) {
mLastTime = System.currentTimeMillis() + 100;
}
setState(STATE_RUNNING);
}
}
/**
* Pauses the physics update & animation.
*/
public void pause() {
synchronized (mSurfaceHolder) {
if (mMode == STATE_RUNNING) setState(STATE_PAUSE);
}
}
@Override
public void run() {
while (mRun) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
if (mMode == STATE_RUNNING) {
updatePhysics();
doDraw(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);
}
}
}
}
private void doDraw(Canvas c) {
if(update) {
canvasTop.drawColor(Color.BLACK);
canvasTop.drawCircle(ballPosition.x, ballPosition.y, SIZE/2, paint);
update=false;
}
// drawing here
// erase the canvas :
c.drawColor(Color.BLACK);
// print the bitmap :
c.drawBitmap(BitmapTop, 0, 0, null);
}
private void updatePhysics() {
now = System.currentTimeMillis();
// Do nothing if mLastTime is in the future.
// This allows the game-start to delay the start of the physics
// by 100ms or whatever.
if (mLastTime > now) return;
double elapsed = (now - mLastTime) / 1000.0;
//Physics here
boolean ok=false;
Point virtualPosition;
do {
virtualPosition=new Point(ballPosition);
// move the virtual point
if(dir==direction.UP) {
virtualPosition.y-=2*elapsed*PHYS_SLEW_SEC;
}else {
virtualPosition.y+=2*elapsed*PHYS_SLEW_SEC;
}
// change the position if it's needed
if( (virtualPosition.y-SIZE_BALL/2)<0 || (virtualPosition.y+SIZE_BALL/2)>H) {
if(dir==direction.UP)dir=direction.DOWN;
else dir=direction.UP;
}else ok=true;
}while(!ok);
// update position
ballPosition=virtualPosition;
// update the bitmap :
update=true;
// update last time
mLastTime = now;
}
///////////
}
public Demoview(Context context, AttributeSet attrs) {
super(context, attrs);
// register our interest in hearing about changes to our surface
SurfaceHolder holder = getHolder();
holder.addCallback(this);
thread = new DemoThread(holder, context);
setFocusable(true); // make sure we get key events
}
public DemoThread getThread() {
return thread;
}
// key manager :
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
keys[ UP ]=true;
}
//
else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
keys[ DOWN ]=true;
}
//
else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
keys[ LEFT ]=true;
}
//
else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
keys[ RIGHT ]=true;
}
//
return true;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent msg) {
if (keyCode == KeyEvent.KEYCODE_DPAD_UP)keys[ UP ]=false;
//
else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN)keys[ DOWN ]=false;
//
else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT)keys[ LEFT ]=false;
//
else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT)keys[ RIGHT ]=false;
//
return true;
}
/**
* Standard window-focus override. Notice focus lost so we can pause on
* focus lost. e.g. user switches to take a call.
*/
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
if (!hasWindowFocus) thread.pause();
}
/* 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 ready 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
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!
*/
public void surfaceDestroyed(SurfaceHolder holder) {
//Log.i("test","destruction surface");
// we have to tell thread to shut down & wait for it to finish, or else
// it might touch the Surface after we return and explode
boolean retry = true;
thread.setRunning(false);
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
}