歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android開發教程:游戲過程中按Home鍵後返回游戲界面

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

日期:2017/3/1 10:55:22   编辑:Linux編程

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