package tadpole2d.game;
import system.LAGraphicsUtils;
import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
//游戏View
public class LAGameView extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "LAGameView";
private static final long MAX_INTERVAL = 1000L;//最大间隔
private static final int fpsX = 5;
private static final int fpsY = 20;
private transient int width, height;
private transient boolean start, running;
private transient long maxFrames, curTime, startTime, offsetTime, curFPS, calcInterval;
private transient double frameCount;
private LAHandler handler;
private SurfaceHolder surfaceHolder;
private CanvasThread canvasThread;
private LAGraphics canvasGraphics;
private LAImage screenImage;
private Rect rect;
private LAScreen curScreen;
/**
* 是否显示fps帧率
*/
private transient boolean showFps = false;
/**
* 判断Surface是否正在活动中
*/
private transient boolean isSurfaceActive = false;
public LAGameView(Activity activity) {
this(activity, false);
}
public LAGameView(Activity activity, boolean isLandScape) {
super(activity.getApplicationContext());
LASystem.gc();
LASystem.setSystemHandler(activity, this);
this.handler = LASystem.getSystemHandler();
// this.handler.setFullScreen();
this.handler.setLandScape(isLandScape);
this.setOnCreateContextMenuListener(handler);
this.setOnFocusChangeListener(handler);
this.setOnLongClickListener(handler);
this.setOnKeyListener(handler);
this.setOnClickListener(handler);
this.setOnTouchListener(handler);
this.screenImage = new LAImage(width = handler.getWidth(), height = handler.getHeight());
this.rect = new Rect(0, 0, width, height);
System.out.println("width=" + width + ",height=" + height);
this.canvasThread = new CanvasThread();
this.surfaceHolder = getHolder();
this.surfaceHolder.addCallback(this);
this.surfaceHolder.setSizeFromLayout();
this.setRunning(true);
this.setFPS(LASystem.DEFAULT_MAX_FPS);
this.canvasGraphics = screenImage.getLAGraphics();
this.setFocusable(true);
this.setFocusableInTouchMode(true);
this.requestFocus();
}
class CanvasThread extends Thread {
public void run() {
final LTimerContext timerContext = new LTimerContext();
timerContext.setMillisTime(startTime = System.currentTimeMillis());
ILAScreen screen = null;
Canvas canvas = null;
do {
if (!start) {
continue;
}
screen = handler.getScreen();
canvasGraphics.drawClear();
screen.createUI(canvasGraphics);
curTime = System.currentTimeMillis();
// 设置上次更新所花时间
timerContext.setSinceLastUpdateTime(curTime - timerContext.getMillisTime());
// 设置睡眠时间
timerContext.setMillisSleepTime((offsetTime - timerContext.getSinceLastUpdateTime()) - timerContext.getMillisOverSleepTime());
if (timerContext.getMillisSleepTime() > 0)//���ÿ֡�ļ��̫�̣�������ʱ��
{
try {
Thread.sleep(timerContext.getMillisSleepTime());
} catch (InterruptedException e) {
}
timerContext.setMillisOverSleepTime((System.currentTimeMillis()) - curTime);
} else {
timerContext.setMillisOverSleepTime(0L);
}
timerContext.setMillisTime(System.currentTimeMillis());
screen.runTimer(timerContext);
if (showFps) {
tickFrames();
canvasGraphics.setColor(Color.WHITE);
canvasGraphics.setAntiAlias(true);
canvasGraphics.drawString(("FPS:" + curFPS).intern(), fpsX, fpsY);
canvasGraphics.setAntiAlias(false);
}
canvas = surfaceHolder.lockCanvas(rect);
canvas.drawBitmap(screenImage.getBitmap(), 0, 0, null);
surfaceHolder.unlockCanvasAndPost(canvas);
try {
Thread.sleep(30);
} catch (InterruptedException e) {
}
LASystem.gc(10000, 1);
} while (running);
destroyView();
}
private void tickFrames() {
frameCount++;
// offsetTime 是理想状态下每刷新一帧所花的时间
calcInterval += offsetTime;
if (calcInterval >= MAX_INTERVAL) {
long timeNow = System.currentTimeMillis();
long realElapsedTime = timeNow - startTime; // 获取间隔实际时间
// 计算FPS.(注:转毫秒为秒)
curFPS = (long) ((frameCount / realElapsedTime) * MAX_INTERVAL);
// 重置数值,以计算下一次FPS
frameCount = 0L;
calcInterval = 0L;
startTime = timeNow;
}
}
}
public void destroyView() {
if (canvasThread != null) {
canvasThread = null;
}
LAGraphicsUtils.destroyImages();
LASystem.gc();
}
public void mainLoop() {
this.handler.getActivity().setContentView(this);
this.startPaint();
}
public void mianStop() {
this.endPaint();
}
public void startPaint() {
this.start = true;
}
public void endPaint() {
this.start = false;
}
public Thread getCanvasThread() {
return canvasThread;
}
public void setScreen(ILAScreen screen) {
this.handler.setScreen(screen);
}
public boolean getRunning() {
return running;
}
public void setRunning(boolean running) {
GLog.d(TAG, "----------%s(%b)----------", "setRunning", running);
this.running = running;
if (this.running == true && isSurfaceActive == true) {
resumeCanvasThread();
}
}
public void setFPS(long frames) {
this.maxFrames = frames;
this.offsetTime = (long) (1.0 / maxFrames * MAX_INTERVAL);
}
public long getMaxFPS() {
return this.maxFrames;
}
public void setShowFPS(boolean isFPS) {
this.showFps = isFPS;
}
public LAHandler getLHandler() {
return handler;
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
GLog.d(TAG, "----------surfaceChanged----------");
GLog.d(TAG, "surfaceDestroyed (width:%d, height:%d)", this.getWidth(), this.getHeight());
holder.setFixedSize(width, height);
}
public void resumeCanvasThread() {
if (canvasThread == null) {
canvasThread = new CanvasThread();
}
if (!canvasThread.isAlive()) {
canvasThread.start();
}
}
public void surfaceCreated(SurfaceHolder holder) {
GLog.d(TAG, "----------surfaceCreated----------");
GLog.d(TAG, "surfaceCreated (width:%d, height:%d)", this.getWidth(), this.getHeight());
isSurfaceActive = true;
LAScreen laScreen = (LAScreen) handler.getScreen();
// if screen change . Fire Screen beforeDraw
if ((curScreen == null) || (!curScreen.equal(laScreen))) {
laScreen.onCreate(this);
}
curScreen = laScreen;
resumeCanvasThread();
}
public void surfaceDestroyed(SurfaceHolder holder) {
isSurfaceActive = false;
GLog.d(TAG, "----------surfaceDestroyed----------");
GLog.d(TAG, "surfaceDestroyed (width:%d, height:%d)", this.getWidth(), this.getHeight());
boolean result = true;
setRunning(false);
while (result) {
try {
//canvasThread.join();
canvasThread = null;
result = false;
} catch (Exception e) {
}
}
}
}