安卓遊戲框架~~

想作個啥遊戲玩玩能夠看看,先記下來。android

 

其主要「實用」之處在於:
1.框架總體很小,上手快,作大遊戲的公司沒多少,作小遊戲的我的開發者鋪天蓋地,相比動則上升到引擎級的龐然大物,小型的框架更加實用,更加考慮大多數開發者的利益。
2.小不等於不完善,之因此剝SDK的遊戲示例代碼的框架出來,就是學習後發現它對於系統事件的處理比較完善,另外我我的還修正了它對於來電處理等異常事件不完美之處,使其更加完善。
R.layout.main 佈局文件
  1.     <?xml version="1.0" encoding="utf-8"?>
  2.     <FrameLayout
  3.         xmlns:android="http://schemas.android.com/apk/res/android"
  4.         android:orientation="vertical"
  5.         android:layout_width="match_parent"
  6.         android:layout_height="match_parent">
  7.         <com.mstanford.gameframework.GameSurfaceView
  8.             android:id="@+id/gameview"
  9.             android:layout_width="match_parent"
  10.             android:layout_height="match_parent" />
  11.         <RelativeLayout
  12.             android:layout_width="match_parent"
  13.             android:layout_height="match_parent">
  14.             <TextView
  15.                 android:id="@+id/textview"
  16.                 android:layout_width="wrap_content"
  17.                 android:layout_height="wrap_content"
  18.                 android:layout_centerInParent="true"
  19.                 android:gravity="center_horizontal"
  20.                 android:textColor="#88ffffff"
  21.                 android:textSize="24sp" />
  22.         </RelativeLayout>
  23.     </FrameLayout>
複製代碼
Activity類
  1.     package com.mstanford.gameframework;
  2.     import com.mstanford.gameframe.R;
  3.     import android.app.Activity;
  4.     import android.os.Bundle;
  5.     import android.util.Log;
  6.     import android.view.Menu;
  7.     import android.view.MenuItem;
  8.     import android.widget.TextView;
  9.     public class GameActivity extends Activity {
  10.     private GameSurfaceView gameSurfaceView;
  11.     private GameThread gameThread;
  12.     @Override
  13.     public void onCreate(Bundle savedInstanceState) {
  14.       super.onCreate(savedInstanceState);
  15.       setContentView(R.layout.main);
  16.       gameSurfaceView = (GameSurfaceView) this.findViewById(R.id.gameview);
  17.       gameThread = gameSurfaceView.getThread();
  18.       gameSurfaceView.setTextView((TextView) findViewById(R.id.textview));
  19.       if (savedInstanceState == null) {
  20.        // 遊戲第一次啓動時,初始化遊戲狀態
  21.        gameThread.doStart();
  22.        Log.w(this.getClass().getName(), "SIS is null");
  23.       }
  24.       else {
  25.        // 從其餘應用界面切迴游戲時,若是Activity從新建立,則恢復上次切出遊戲時的各項數據
  26.        gameThread.restoreState(savedInstanceState);
  27.        Log.w(this.getClass().getName(), "SIS is nonnull");
  28.       }
  29.     }
  30.     /**
  31.       * 當Activity被切換到後臺時調用,存儲Activity從新建立時須要恢復的遊戲數據
  32.       */
  33.     @Override
  34.     protected void onSaveInstanceState(Bundle outState) {
  35.       super.onSaveInstanceState(outState);
  36.       gameThread.saveState(outState);
  37.       Log.w(this.getClass().getName(), "SIS called");
  38.     }
  39.     /**
  40.       * 當Activity被切換到後臺時調用,在這裏對遊戲作"暫停"的處理
  41.       */
  42.     @Override
  43.     protected void onPause() {
  44.       super.onPause();
  45.       // 暫停遊戲
  46.       gameSurfaceView.getThread().pause();
  47.     }
  48.     /**
  49.       * 當Activity切換到前臺時調用
  50.       */
  51.     @Override
  52.     protected void onResume() {
  53.       super.onResume();
  54.       // 遊戲結束暫停狀態,遊戲正常進行
  55.       gameSurfaceView.getThread().unpause();
  56.     }
  57.     /**
  58.       * 建立遊戲菜單
  59.       */
  60.     @Override
  61.     public boolean onCreateOptionsMenu(Menu menu) {
  62.       // TODO Auto-generated method stub
  63.       return super.onCreateOptionsMenu(menu);
  64.     }
  65.     /**
  66.       * 定義遊戲菜單的點擊事件處理
  67.       */
  68.     @Override
  69.     public boolean onOptionsItemSelected(MenuItem item) {
  70.       // TODO Auto-generated method stub
  71.       return super.onOptionsItemSelected(item);
  72.     }
  73.     @Override
  74.     protected void onDestroy() {
  75.       super.onDestroy();
  76.       Log.v(this.getClass().getName(), "onDestroy");
  77.       
  78.       //中止遊戲
  79.       gameThread.setRunning(false);
  80.       boolean retry = true;
  81.       while (retry) {
  82.        try {
  83.         //阻塞Activity的主線程直到遊戲線程執行完
  84.         gameThread.join();
  85.         retry = false;
  86.        } catch (InterruptedException e) {
  87.        }
  88.       }
  89.     }
  90.     }
複製代碼
SurfaceView類
  1.     package com.mstanford.gameframework;
  2.     import android.content.Context;
  3.     import android.os.Handler;
  4.     import android.os.Message;
  5.     import android.util.AttributeSet;
  6.     import android.util.Log;
  7.     import android.view.KeyEvent;
  8.     import android.view.SurfaceHolder;
  9.     import android.view.SurfaceView;
  10.     import android.view.SurfaceHolder.Callback;
  11.     import android.widget.TextView;
  12.     public class GameSurfaceView extends SurfaceView implements Callback {
  13.     private GameThread gameThread;
  14.     private TextView textview;
  15.     public GameSurfaceView(Context context, AttributeSet attrs) {
  16.       super(context, attrs);
  17.       SurfaceHolder holder = getHolder();
  18.       holder.addCallback(this);
  19.       gameThread = new GameThread(holder, context, new Handler() {
  20.        @Override
  21.        public void handleMessage(Message m) {
  22.         textview.setText(m.getData().getString("text"));
  23.        }
  24.       });
  25.       // 設置可得到焦點,確保能捕獲到KeyEvent
  26.       setFocusable(true);
  27.     }
  28.     /**
  29.       * 獲取一個Activity傳來的View協助SurfaceView顯示遊戲視圖,View的具體類型能夠根據遊戲須要來定
  30.       */
  31.     public void setTextView(TextView view) {
  32.       this.textview = view;
  33.     }
  34.     public GameThread getThread() {
  35.       return gameThread;
  36.     }
  37.     @Override
  38.     public boolean onKeyDown(int keyCode, KeyEvent event) {
  39.       return gameThread.doKeyDown(keyCode, event);
  40.     }
  41.     @Override
  42.     public boolean onKeyUp(int keyCode, KeyEvent event) {
  43.       return gameThread.doKeyUp(keyCode, event);
  44.     }
  45.     /**
  46.       * 當SurfaceView獲得或失去焦點時調用,使遊戲暫停/恢復運行,
  47.       */
  48.     @Override
  49.     public void onWindowFocusChanged(boolean hasWindowFocus) {
  50.       if (!hasWindowFocus) {
  51.        gameThread.pause();
  52.       }
  53.       else {
  54.        gameThread.unpause();
  55.       }
  56.     }
  57.     @Override
  58.     public void surfaceChanged(SurfaceHolder holder, int format, int width,
  59.        int height) {
  60.       Log.v(this.getClass().getName(), "surfaceChanged()");
  61.       gameThread.setSurfaceSize(width, height);
  62.       gameThread.setRunning(true);
  63.       if (gameThread.isAlive()) {
  64.        Log.v(this.getClass().getName(), "unpause gameThread");
  65.        gameThread.unpause();
  66.       }
  67.       else {
  68.        Log.v(this.getClass().getName(), "start gameThread");
  69.        gameThread.start();
  70.       }
  71.     }
  72.     @Override
  73.     public void surfaceCreated(SurfaceHolder holder) {
  74.       Log.v(this.getClass().getName(), "surfaceCreated()");
  75.       }
  76.     /**
  77.       * 爲防止surface還會被建立(好比來電)致使gameThread再次啓動出現錯誤,且Activity的onPause方法中已作暫停處理,
  78.       * 這邊不對gameThread作處理
  79.       * @param holder
  80.       */
  81.     @Override
  82.     public void surfaceDestroyed(SurfaceHolder holder) {
  83.       Log.v(this.getClass().getName(), "surfaceDestroyed");
  84.     }
複製代碼
遊戲線程類
  1.     package com.mstanford.gameframework;
  2.     import android.content.Context;
  3.     import android.graphics.Canvas;
  4.     import android.os.Bundle;
  5.     import android.os.Handler;
  6.     import android.util.Log;
  7.     import android.view.KeyEvent;
  8.     import android.view.SurfaceHolder;
  9.     public class GameThread extends Thread {
  10.     // 遊戲狀態值:ready
  11.     public final static int GS_READY = 0;
  12.     //遊戲線程每執行一次須要睡眠的時間
  13.     private final static int DELAY_TIME = 100;
  14.     //上下文,方便獲取到應用的各項資源,如圖片、音樂、字符串等
  15.     private Context context;
  16.     //與Activity其餘View交互用的handler
  17.     private Handler handler;
  18.     //由SurfaceView提供的SurfaceHolder
  19.     private SurfaceHolder surfaceHolder;
  20.     //遊戲線程運行開關
  21.     private boolean running = false;
  22.     //遊戲狀態
  23.     private int gameState;
  24.     //當前surface/canvas的高度,在surfaceChanged方法中被設置
  25.         private int mCanvasHeight = 1;
  26.       //當前surface/canvas的寬度,在surfaceChanged方法中被設置
  27.         private int mCanvasWidth = 1;
  28.       
  29.         /**
  30.          * 遊戲是否暫停
  31.          */
  32.         private boolean isPaused = false;
  33.     public GameThread(SurfaceHolder holder, Context context, Handler handler) {
  34.       this.surfaceHolder = holder;
  35.       this.context = context;
  36.       this.handler = handler;
  37.     }
  38.     /**
  39.       * 設置遊戲狀態
  40.       * @param mode 遊戲狀態
  41.       */
  42.     public void setState(int mode) {
  43.       synchronized (surfaceHolder) {
  44.        setState(mode, null);
  45.       }
  46.     }
  47.     /**
  48.       * 設置遊戲狀態
  49.       * @param mode 遊戲狀態
  50.       * @param message 設置遊戲狀態時的附加文字信息
  51.       */
  52.     public void setState(int mode, CharSequence message) {
  53.       synchronized (surfaceHolder) {
  54.        // TODO
  55.       }
  56.     }
  57.     /**
  58.       * 暫停遊戲
  59.       */
  60.     public void pause() {
  61.       synchronized (surfaceHolder) {
  62.        isPaused = true;
  63.       }
  64.     }
  65.     /**
  66.       * 恢復運行遊戲
  67.       */
  68.     public void unpause() {
  69.       //若是遊戲中有時間,別忘記應將其在這裏調整到正常
  70.       synchronized (surfaceHolder) {
  71.        isPaused = false;
  72.       }
  73.     }
  74.     /**
  75.       * 當Activity因銷燬而被從新建立時,在這裏恢復遊戲上次運行的數據
  76.       * @param saveState Activity傳來的保存遊戲數據的容器
  77.       */
  78.     public void restoreState(Bundle saveState) {
  79.       //TODO
  80.     }
  81.     /**
  82.       * 在Activity切到後臺時保存遊戲的數據
  83.       * @param outState 保存遊戲數據的容器
  84.       */
  85.     public void saveState(Bundle outState)
  86.     {
  87.       //TODO
  88.     }
  89.     /**
  90.       * 設置遊戲線程運行開關
  91.       * @param b 開/關
  92.       */
  93.     public void setRunning(boolean b) {
  94.       running = b;
  95.     }
  96.     /**
  97.       * 處理按下按鍵的事件
  98.       * @param keyCode 按鍵事件動做值
  99.       * @param msg 按鍵事件對象
  100.       * @return 是否處理完
  101.       */
  102.     public boolean doKeyDown(int keyCode, KeyEvent msg) {
  103.       synchronized (surfaceHolder) {
  104.        // TODO
  105.        return false;
  106.       }
  107.     }
  108.     /**
  109.       * 處理彈起按鍵的事件
  110.       * @param keyCode 按鍵事件動做值
  111.       * @param msg 按鍵事件對象
  112.       * @return 是否處理完
  113.       */
  114.     public boolean doKeyUp(int keyCode, KeyEvent msg) {
  115.       synchronized (surfaceHolder) {
  116.        // TODO
  117.       }
  118.       return false;
  119.     }
  120.     /**
  121.       * 設置surface/canvas的寬度和高度
  122.       * @param width 由SurfaceHolder傳來的寬度
  123.       * @param height 由SurfaceHolder傳來的高度
  124.       */
  125.     public void setSurfaceSize(int width, int height) {
  126.       // synchronized to make sure these all change atomically
  127.       synchronized (surfaceHolder) {
  128.        mCanvasWidth = width;
  129.        mCanvasHeight = height;
  130.        //不要忘記每次畫布的寬度和高度改變時, 在這裏對圖片等資源作縮放等相關適配屏幕的處理
  131.        //TODO
  132.       }
  133.     }
  134.     public void run() {
  135.       while (running) {
  136.        if (!isPaused) {
  137.         Canvas c = null;
  138.         try {
  139.          c = surfaceHolder.lockCanvas(null);
  140.          synchronized (surfaceHolder) {
  141.           doDraw(c);
  142.          }
  143.          logic();
  144.         } finally {
  145.          if (c != null) {
  146.           surfaceHolder.unlockCanvasAndPost(c);
  147.          }
  148.         }
  149.         try {
  150.          Thread.sleep(DELAY_TIME);
  151.         } catch (InterruptedException e) {
  152.          e.printStackTrace();
  153.         }
  154.        }
  155.       }
  156.     }
  157.     /**
  158.       * 遊戲邏輯處理
  159.       */
  160.     public void logic()
  161.     {
  162.       Log.v(this.getClass().getName(), "logic");
  163.       //TODO
  164.     }
  165.     /**
  166.       * 遊戲繪畫
  167.       */
  168.     private void doDraw(Canvas canvas) {
  169.       Log.v(this.getClass().getName(), "doDraw");
  170.       //TODO
  171.     }
  172.     /**
  173.       * 初始化遊戲開始時的參數
  174.       */
  175.     private void doStart() {
  176.       //TODO
  177.     }
  178.     }
相關文章
相關標籤/搜索