其主要「實用」之處在於:
1.框架總體很小,上手快,作大遊戲的公司沒多少,作小遊戲的我的開發者鋪天蓋地,相比動則上升到引擎級的龐然大物,小型的框架更加實用,更加考慮大多數開發者的利益。
2.小不等於不完善,之因此剝SDK的遊戲示例代碼的框架出來,就是學習後發現它對於系統事件的處理比較完善,另外我我的還修正了它對於來電處理等異常事件不完美之處,使其更加完善。
R.layout.main 佈局文件
- <?xml version="1.0" encoding="utf-8"?>
- <FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <com.mstanford.gameframework.GameSurfaceView
- android:id="@+id/gameview"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <TextView
- android:id="@+id/textview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:gravity="center_horizontal"
- android:textColor="#88ffffff"
- android:textSize="24sp" />
- </RelativeLayout>
- </FrameLayout>
複製代碼
Activity類
- package com.mstanford.gameframework;
- import com.mstanford.gameframe.R;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.widget.TextView;
- public class GameActivity extends Activity {
- private GameSurfaceView gameSurfaceView;
- private GameThread gameThread;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- gameSurfaceView = (GameSurfaceView) this.findViewById(R.id.gameview);
- gameThread = gameSurfaceView.getThread();
- gameSurfaceView.setTextView((TextView) findViewById(R.id.textview));
- if (savedInstanceState == null) {
- // 遊戲第一次啓動時,初始化遊戲狀態
- gameThread.doStart();
- Log.w(this.getClass().getName(), "SIS is null");
- }
- else {
- // 從其餘應用界面切迴游戲時,若是Activity從新建立,則恢復上次切出遊戲時的各項數據
- gameThread.restoreState(savedInstanceState);
- Log.w(this.getClass().getName(), "SIS is nonnull");
- }
- }
- /**
- * 當Activity被切換到後臺時調用,存儲Activity從新建立時須要恢復的遊戲數據
- */
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- gameThread.saveState(outState);
- Log.w(this.getClass().getName(), "SIS called");
- }
- /**
- * 當Activity被切換到後臺時調用,在這裏對遊戲作"暫停"的處理
- */
- @Override
- protected void onPause() {
- super.onPause();
- // 暫停遊戲
- gameSurfaceView.getThread().pause();
- }
- /**
- * 當Activity切換到前臺時調用
- */
- @Override
- protected void onResume() {
- super.onResume();
- // 遊戲結束暫停狀態,遊戲正常進行
- gameSurfaceView.getThread().unpause();
- }
- /**
- * 建立遊戲菜單
- */
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // TODO Auto-generated method stub
- return super.onCreateOptionsMenu(menu);
- }
- /**
- * 定義遊戲菜單的點擊事件處理
- */
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // TODO Auto-generated method stub
- return super.onOptionsItemSelected(item);
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- Log.v(this.getClass().getName(), "onDestroy");
-
- //中止遊戲
- gameThread.setRunning(false);
- boolean retry = true;
- while (retry) {
- try {
- //阻塞Activity的主線程直到遊戲線程執行完
- gameThread.join();
- retry = false;
- } catch (InterruptedException e) {
- }
- }
- }
- }
複製代碼
SurfaceView類
- package com.mstanford.gameframework;
- import android.content.Context;
- import android.os.Handler;
- import android.os.Message;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.KeyEvent;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
- import android.view.SurfaceHolder.Callback;
- import android.widget.TextView;
- public class GameSurfaceView extends SurfaceView implements Callback {
- private GameThread gameThread;
- private TextView textview;
- public GameSurfaceView(Context context, AttributeSet attrs) {
- super(context, attrs);
- SurfaceHolder holder = getHolder();
- holder.addCallback(this);
- gameThread = new GameThread(holder, context, new Handler() {
- @Override
- public void handleMessage(Message m) {
- textview.setText(m.getData().getString("text"));
- }
- });
- // 設置可得到焦點,確保能捕獲到KeyEvent
- setFocusable(true);
- }
- /**
- * 獲取一個Activity傳來的View協助SurfaceView顯示遊戲視圖,View的具體類型能夠根據遊戲須要來定
- */
- public void setTextView(TextView view) {
- this.textview = view;
- }
- public GameThread getThread() {
- return gameThread;
- }
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- return gameThread.doKeyDown(keyCode, event);
- }
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- return gameThread.doKeyUp(keyCode, event);
- }
- /**
- * 當SurfaceView獲得或失去焦點時調用,使遊戲暫停/恢復運行,
- */
- @Override
- public void onWindowFocusChanged(boolean hasWindowFocus) {
- if (!hasWindowFocus) {
- gameThread.pause();
- }
- else {
- gameThread.unpause();
- }
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- Log.v(this.getClass().getName(), "surfaceChanged()");
- gameThread.setSurfaceSize(width, height);
- gameThread.setRunning(true);
- if (gameThread.isAlive()) {
- Log.v(this.getClass().getName(), "unpause gameThread");
- gameThread.unpause();
- }
- else {
- Log.v(this.getClass().getName(), "start gameThread");
- gameThread.start();
- }
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- Log.v(this.getClass().getName(), "surfaceCreated()");
- }
- /**
- * 爲防止surface還會被建立(好比來電)致使gameThread再次啓動出現錯誤,且Activity的onPause方法中已作暫停處理,
- * 這邊不對gameThread作處理
- * @param holder
- */
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- Log.v(this.getClass().getName(), "surfaceDestroyed");
- }
複製代碼
遊戲線程類
- package com.mstanford.gameframework;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.os.Bundle;
- import android.os.Handler;
- import android.util.Log;
- import android.view.KeyEvent;
- import android.view.SurfaceHolder;
- public class GameThread extends Thread {
- // 遊戲狀態值:ready
- public final static int GS_READY = 0;
- //遊戲線程每執行一次須要睡眠的時間
- private final static int DELAY_TIME = 100;
- //上下文,方便獲取到應用的各項資源,如圖片、音樂、字符串等
- private Context context;
- //與Activity其餘View交互用的handler
- private Handler handler;
- //由SurfaceView提供的SurfaceHolder
- private SurfaceHolder surfaceHolder;
- //遊戲線程運行開關
- private boolean running = false;
- //遊戲狀態
- private int gameState;
- //當前surface/canvas的高度,在surfaceChanged方法中被設置
- private int mCanvasHeight = 1;
- //當前surface/canvas的寬度,在surfaceChanged方法中被設置
- private int mCanvasWidth = 1;
-
- /**
- * 遊戲是否暫停
- */
- private boolean isPaused = false;
- public GameThread(SurfaceHolder holder, Context context, Handler handler) {
- this.surfaceHolder = holder;
- this.context = context;
- this.handler = handler;
- }
- /**
- * 設置遊戲狀態
- * @param mode 遊戲狀態
- */
- public void setState(int mode) {
- synchronized (surfaceHolder) {
- setState(mode, null);
- }
- }
- /**
- * 設置遊戲狀態
- * @param mode 遊戲狀態
- * @param message 設置遊戲狀態時的附加文字信息
- */
- public void setState(int mode, CharSequence message) {
- synchronized (surfaceHolder) {
- // TODO
- }
- }
- /**
- * 暫停遊戲
- */
- public void pause() {
- synchronized (surfaceHolder) {
- isPaused = true;
- }
- }
- /**
- * 恢復運行遊戲
- */
- public void unpause() {
- //若是遊戲中有時間,別忘記應將其在這裏調整到正常
- synchronized (surfaceHolder) {
- isPaused = false;
- }
- }
- /**
- * 當Activity因銷燬而被從新建立時,在這裏恢復遊戲上次運行的數據
- * @param saveState Activity傳來的保存遊戲數據的容器
- */
- public void restoreState(Bundle saveState) {
- //TODO
- }
- /**
- * 在Activity切到後臺時保存遊戲的數據
- * @param outState 保存遊戲數據的容器
- */
- public void saveState(Bundle outState)
- {
- //TODO
- }
- /**
- * 設置遊戲線程運行開關
- * @param b 開/關
- */
- public void setRunning(boolean b) {
- running = b;
- }
- /**
- * 處理按下按鍵的事件
- * @param keyCode 按鍵事件動做值
- * @param msg 按鍵事件對象
- * @return 是否處理完
- */
- public boolean doKeyDown(int keyCode, KeyEvent msg) {
- synchronized (surfaceHolder) {
- // TODO
- return false;
- }
- }
- /**
- * 處理彈起按鍵的事件
- * @param keyCode 按鍵事件動做值
- * @param msg 按鍵事件對象
- * @return 是否處理完
- */
- public boolean doKeyUp(int keyCode, KeyEvent msg) {
- synchronized (surfaceHolder) {
- // TODO
- }
- return false;
- }
- /**
- * 設置surface/canvas的寬度和高度
- * @param width 由SurfaceHolder傳來的寬度
- * @param height 由SurfaceHolder傳來的高度
- */
- public void setSurfaceSize(int width, int height) {
- // synchronized to make sure these all change atomically
- synchronized (surfaceHolder) {
- mCanvasWidth = width;
- mCanvasHeight = height;
- //不要忘記每次畫布的寬度和高度改變時, 在這裏對圖片等資源作縮放等相關適配屏幕的處理
- //TODO
- }
- }
- public void run() {
- while (running) {
- if (!isPaused) {
- Canvas c = null;
- try {
- c = surfaceHolder.lockCanvas(null);
- synchronized (surfaceHolder) {
- doDraw(c);
- }
- logic();
- } finally {
- if (c != null) {
- surfaceHolder.unlockCanvasAndPost(c);
- }
- }
- try {
- Thread.sleep(DELAY_TIME);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- /**
- * 遊戲邏輯處理
- */
- public void logic()
- {
- Log.v(this.getClass().getName(), "logic");
- //TODO
- }
- /**
- * 遊戲繪畫
- */
- private void doDraw(Canvas canvas) {
- Log.v(this.getClass().getName(), "doDraw");
- //TODO
- }
- /**
- * 初始化遊戲開始時的參數
- */
- private void doStart() {
- //TODO
- }
- }