歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android開發教程:游戲過程中按Home鍵後返回游戲界面

症狀:游戲過程中,按下Home鍵返回手機主菜單,再點擊游戲圖標試圖返回游戲的時候屏幕黑的一片!

以前一直沒在意只有結束線程在運行游戲,今天覺得改仔細琢磨一下這個問題了!

首先第一件事:打印Logo看看按下Home鍵後會調用哪些方法,結果如下:

游戲過程中按下Home後:

11-29 20:42:07.090: I/System.out(18835): Activity onPause...
11-29 20:42:14.190: I/System.out(18835): Activity  onStop...
11-29 20:42:14.260: I/System.out(18835): SurfaceView surfaceDestroyed...

可見SurfaceView 在返回手機主菜單的時候被銷毀了,而我的SurfaceView 主線程是在構造方法裡創建的

那麼我們返回游戲的時候會調哪些方法呢?接著看Log:

11-29 20:48:06.940: I/System.out(18835): Activity  onRestart...
11-29 20:48:06.950: I/System.out(18835): Activity  onResume...
11-29 20:48:07.230: I/System.out(18835): SurfaceView  surfaceCreated...
11-29 20:48:07.240: I/System.out(18835): SurfaceView  surfaceChanged...

surfaceDestroyed 的時候線程已經退出了運行,這時再返回到游戲刷屏的線程就沒了,任何繪制方法都沒調用,所以你看到的只有黑漆漆的屏幕啦!
明白了運行原理我們就知道改怎麼做啦!

首先創建線程放在 surfaceCreated ,並啟動線程,

當 surfaceDestroyed 調用的時候,線程已經無效了,我們把線程對象設為null釋放他,

然後不管怎麼返回線程都會繼續運行你的游戲也就不會中斷了,來段簡單的代碼更具表達力度!

  1. package com.game.view;  
  2.   
  3. import Android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Paint;  
  6. import android.graphics.Paint.Style;  
  7. import android.graphics.Rect;  
  8. import android.view.SurfaceHolder;  
  9. import android.view.SurfaceHolder.Callback;  
  10. import android.view.SurfaceView;  
  11.   
  12. public class TestView extends SurfaceView implements Callback, Runnable{  
  13.     public static final int GAME_HEART = 1000/30;   //每秒刷新30次   
  14.       
  15.     public static int screenW, screenH;  
  16.       
  17.     private Thread thread;  
  18.     private SurfaceHolder holder;  
  19.     private Paint paint;  
  20.       
  21.     public TestView(Context context) {  
  22.         super(context);  
  23.         // TODO Auto-generated constructor stub   
  24.         holder = getHolder();  
  25.         holder.addCallback(this);  
  26.           
  27.         paint = new Paint(Paint.ANTI_ALIAS_FLAG);// 無鋸齒   
  28.         paint.setStyle(Style.FILL); //填充樣式   
  29.         paint.setTextSize(16); // 字體大小   
  30.     }  
  31.   
  32.     /** 
  33.      * 執行游戲邏輯方法 
  34.      */  
  35.     private void update() {  
  36.           
  37.     }  
  38.       
  39.     /** 
  40.      * 執行游戲繪制 
  41.      */  
  42.     private Rect rect = new Rect();  
  43.     private void draw(){  
  44.         Canvas canvas = holder.lockCanvas();  
  45.           
  46.         String text = "天使之翼的示例Demo";  
  47.         //獲取文本寬高   
  48.         paint.getTextBounds(text, 0, text.length(), rect);  
  49.         //在屏幕中央位置顯示文本   
  50.         paint.setColor(0xfff000f0); //注意最高兩位 ff 代表畫筆透明度,不設置的畫就是完全透明了,看不到任何效果   
  51.         canvas.drawText(text,   
  52.                 (screenW - rect.width())/2,   
  53.                 screenH/2 + rect.height()/2,   
  54.                 paint);  
  55.           
  56.         holder.unlockCanvasAndPost(canvas);  
  57.     }  
  58.       
  59.     @Override  
  60.     public void surfaceCreated(SurfaceHolder holder) {  
  61.         // TODO Auto-generated method stub   
  62.         screenW = getWidth();  
  63.         screenH = getHeight();  
  64.           
  65.         thread = new Thread(this);  
  66.         isRun = true;  
  67.         thread.start();  
  68.     }  
  69.   
  70.     @Override  
  71.     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
  72.         // TODO Auto-generated method stub   
  73.         //當屏幕旋轉的時候重新獲取屏幕寬高   
  74.         screenW = getWidth();  
  75.         screenH = getHeight();  
  76.     }  
  77.   
  78.     @Override  
  79.     public void surfaceDestroyed(SurfaceHolder holder) {  
  80.         // TODO Auto-generated method stub   
  81.         isRun = false;  
  82.         thread = null;  
  83.     }  
  84.   
  85.     private boolean isRun;  //線程運行標志   
  86.     private int useTime;    //記錄每次刷屏使用的時間   
  87.     @Override  
  88.     public void run() {  
  89.         // TODO Auto-generated method stub   
  90.         long start, end;  
  91.           
  92.         while(isRun){  
  93.             start = System.currentTimeMillis();  
  94.             update(); // 刷新界面上所有元素   
  95.             draw(); // 繪制界面元素   
  96.             end = System.currentTimeMillis();  
  97.             useTime = (int) (end - start);  
  98.               
  99.             if(useTime < GAME_HEART){    //保證每次刷屏時間間隔相同   
  100.                 try {  
  101.                     Thread.sleep(GAME_HEART - useTime);  
  102.                 } catch (InterruptedException e) {  
  103.                     // TODO Auto-generated catch block   
  104.                     e.printStackTrace();  
  105.                 }  
  106.             }  
  107.         }  
  108.     }  
  109. }  
Copyright © Linux教程網 All Rights Reserved