android遊戲開發——筆記整理之SurfaceView遊戲架構整理

來源:互聯網
上載者:User

   最近一直在讀《android遊戲編程之從零開始》,文章寫的不錯,感覺作者毫不吝嗇的講述了自己開發所學知識與遇到的問題,讀後很有收穫。在此整理下,第五章——遊戲開發實戰的筆記,學習鞏固開發遊戲的整體流程。

   一、用到的是SurfaceView遊戲架構

        由於遊戲中會定期更新畫布,以及雙緩衝機制,所以SurfaceView更加適合遊戲的開發。

       1、先複習下SurfaceView遊戲開發的架構

           public calss MySurfaceView() extends SurfaceView implements Callback,Runnable {

                    private SufaceHolder sfh;//用於控制SurfaceView的大小,格式等,並監聽SurfaceView的狀態。SurfaceView只是儲存當前視圖的像素資料,

                                                       //我們並不會跟SurfaceView打交道,都是通過SurfaceHolder來控制,使用SurfaceHolder的lockCanvas()函數獲得

                                                        //SurfaceView上的Canvas對象,然後通過在Canvas上繪製內容修改SurfaceView中的資料。總體來說是種間接的形式。

                   private Paint paint;

                   private Thread th;//因為會涉及到畫布的更新,刷屏,所以要單獨使用一個線程,去更新,這樣就不會由於更新畫面的時間過長,而導致主UI線程

                                             //被繪製函數所堵塞,引發無法響應按鍵、觸屏等操作。做個文字隨手指移動的例子,當你去掉線程的時候,當不點擊螢幕了,文字還在不斷的動

                  private boolean flag;//線程標識位,銷毀線程的一個標識位,此外,還有防止重複建立線程以及程式異常的作用

                  private Canvas canvas;

                  private int screenW,screenH;

                  public MySurfaceView(Context context)  //主要負責視圖的載入

                  {

                          建立SurfaceHolder執行個體,為SurfaceHolder添加監聽,執行個體化畫筆,設定顏色,設定焦點,載入圖片,初始化遊戲介面等等這些初始化的東西

                   }

                   @Override

                   public void SurfaceCreated(SurfaceHolder holder)

                   {

                              screenW = this.getWidth(); //只能在視圖建立函數中才能獲得視圖的高寬

                              screenH  = this.getHeight();

                              flag  =  true;

                              th = new thread(this);  //為了避免按 Back 跟Home鍵時,會出現線程數量增加以及異常,

                                                               //所以把線程的建立以及啟動放到視圖建立函數中,flag=false放到視圖銷毀函數中

                              th.start();

                    }

                    //自訂的繪圖函數

                    public void myDraw()

                    {

                           try{    //這裡使用try-catch-finally異常處理,是因為當SurfaceView不可編輯或尚未建立時,調用lockCanvas()函數會返回null,

                                                                                                        //如果返回null,再對canvas上進行繪圖就會產生錯誤

                                      canvas = sfh.lockCanvas();//擷取畫布

                                      if(canvas != null)

                                           {

                                                      刷屏跟繪圖

                                            }

                                 }catch(Exception e){ }

                           finally{

                                        if(canvas != null)    //在提交畫布之前出錯,解鎖提交畫布函數無法被執行,就會導致下次通過locakCanvas擷取畫布時拋出異常。

                                                                                          //所以放到finally中解鎖提交畫布

                                             sfh.unlockCanvasAndPost(canvas);

                                   }

                     }

                     public void logic(){//遊戲邏輯相關代碼}

                     @Override

                     public void run() {   //線程時時更新畫布,以及遊戲元素的狀態

                             while(flag){

                                       long start = System.currentTimeMils();

                                       myDraw();

                                       logic();

                                       long end = System.currentTimeMils();

                                       try{

                                           } catch(InterruptedException e)  {e.printStackTrace()}

                              }

                         還有按鍵監聽,觸屏監聽等函數.

                     }

 

在部落格園看到了關於SurfaceView分析不錯的文章,截取一部分,學習學習

原文地址:http://www.cnblogs.com/xuling/archive/2011/06/06/android.html

 

首先我們先來看下官方API對SurfaceView的介紹

SurfaceView的API介紹

Provides a dedicated drawing surface embedded inside of a view hierarchy. You can control the format of this surface and, if you like, its size; the SurfaceView takes care of placing the surface at the correct location on the screen

The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed. The view hierarchy will take care of correctly compositing with the Surface any siblings of the SurfaceView that would normally appear on top of it. This can be used to place overlays such as buttons on top of the Surface, though note however that it can have an impact on performance since a full alpha-blended composite will be performed each time the Surface changes.

Access to the underlying surface is provided via the SurfaceHolder interface, which can be retrieved by calling getHolder().

The Surface will be created for you while the SurfaceView's window is visible; you should implement surfaceCreated(SurfaceHolder) and surfaceDestroyed(SurfaceHolder) to discover when the Surface is created and destroyed as the window is shown and hidden.

One of the purposes of this class is to provide a surface in which a secondary thread can render in to the screen. If you are going to use it this way, you need to be aware of some threading semantics:

•All SurfaceView and SurfaceHolder.Callback methods will be called from the thread running the SurfaceView's window (typically the main thread of the application). They thus need to correctly synchronize with any state that is also touched by the drawing thread.
•You must ensure that the drawing thread only touches the underlying Surface while it is valid -- between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed().
對應的中文翻譯
SurfaceView是視圖(View)的繼承類,這個視圖裡內嵌了一個專門用於繪製的Surface。你可以控制這個Surface的格式和尺寸。Surfaceview控制這個Surface的繪製位置。
        surface是縱深排序(Z-ordered)的,這表明它總在自己所在視窗的後面。surfaceview提供了一個可見地區,只有在這個可見地區內 的surface部分內容才可見,可見地區外的部分不可見。surface的排版顯示受到視圖層級關係的影響,它的兄弟視圖結點會在頂端顯示。這意味者 surface的內容會被它的兄弟視圖遮擋,這一特性可以用來放置遮蓋物(overlays)(例如,文本和按鈕等控制項)。注意,如果surface上面 有透明控制項,那麼它的每次變化都會引起架構重新計算它和頂層控制項的透明效果,這會影響效能。
        你可以通過SurfaceHolder介面訪問這個surface,getHolder()方法可以得到這個介面。
        surfaceview變得可見時,surface被建立;surfaceview隱藏前,surface被銷毀。這樣能節省資源。如果你要查看 surface被建立和銷毀的時機,可以重載surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder)。
        surfaceview的核心在於提供了兩個線程:UI線程和渲染線程。這裡應注意:
        1> 所有SurfaceView和SurfaceHolder.Callback的方法都應該在UI線程裡調用,一般來說就是應用程式主線程。渲染線程所要訪問的各種變數應該作同步處理。
        2> 由於surface可能被銷毀,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之間有效,所以要確保渲染線程訪問的是合法有效surface。

 

接下來呢,說說自己對它的理解
1、定義

可以直接從記憶體或者DMA等硬體介面取得映像資料,是個非常重要的繪圖容器。

它的特性是:可以在主線程之外的線程中向螢幕繪圖上。這樣可以避免畫圖任務繁重的時候造成主線程阻塞,從而提高了程式的反應速度。在遊戲開發中多用到SurfaceView,遊戲中的背景、人物、動畫等等盡量在畫布canvas中畫出。

2、實現

首先繼承SurfaceView並實現SurfaceHolder.Callback介面
使用介面的原因:因為使用SurfaceView 有一個原則,所有的繪圖工作必須得在Surface 被建立之後才能開始(Surface—表面,這個概念在 圖形編程中常常被提到。基本上我們可以把它當作顯存的一個映射,寫入到Surface 的內容
                      可以被直接複製到顯存從而顯示出來,這使得顯示速度會非常快),而在Surface 被銷毀之前必須結束。所以Callback 中的surfaceCreated 和surfaceDestroyed 就成了繪圖處理代碼的邊界。

需要重寫的方法

 (1)public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){}

     //在surface的大小發生改變時激發

 (2)public void surfaceCreated(SurfaceHolder holder){}

     //在建立時激發,一般在這裡調用畫圖的線程。

 (3)public void surfaceDestroyed(SurfaceHolder holder) {}

     //銷毀時激發,一般在這裡將畫圖的線程停止、釋放。

整個過程:繼承SurfaceView並實現SurfaceHolder.Callback介面 ----> SurfaceView.getHolder()獲得SurfaceHolder對象 ---->SurfaceHolder.addCallback(callback)添加回呼函數---->SurfaceHolder.lockCanvas()獲得Canvas對象並鎖定畫布----> Canvas繪畫 ---->SurfaceHolder.unlockCanvasAndPost(Canvas canvas)結束鎖定畫圖,並提交改變,將圖形顯示。

3、SurfaceHolder
這裡用到了一個類SurfaceHolder,可以把它當成surface的控制器,用來操縱surface。處理它的Canvas上畫的效果和動畫,控製表面,大小,像素等。
幾個需要注意的方法:
(1)、abstract void addCallback(SurfaceHolder.Callback callback);
// 給SurfaceView當前的持有人一個回調對象。
(2)、abstract Canvas lockCanvas();
// 鎖定畫布,一般在鎖定後就可以通過其返回的畫布對象Canvas,在其上面畫圖等操作了。
(3)、abstract Canvas lockCanvas(Rect dirty);
// 鎖定畫布的某個地區進行畫圖等..因為畫完圖後,會調用下面的unlockCanvasAndPost來改變顯示內容。
// 相對部分記憶體要求比較高的遊戲來說,可以不用重畫dirty外的其它地區的像素,可以提高速度。
(4)、abstract void unlockCanvasAndPost(Canvas canvas);
// 結束鎖定畫圖,並提交改變。

 

 

 

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.