Android之View和SurfaceView

 轉自Android之View和SurfaceView
 Android遊戲當中主要的除了控制類外就是顯示類View。SurfaceView是從View基類中派生出來的顯示類。android遊戲開發中常用的三種視圖是:view、SurfaceView和GLSurfaceView。

  View:顯示視圖,內置畫布,提供圖形繪製函數、觸屏事件、按鍵事件函數等;必須在UI主線程內更新畫面,速度較慢。

  SurfaceView:基於view視圖進行拓展的視圖類,更適合2D遊戲的開發;是view的子類,類似使用雙緩機制,在新的線程中更新畫面所以刷新界面速度比view快。

  GLSurfaceView:基於SurfaceView視圖再次進行拓展的視圖類,專用於3D遊戲開發的視圖;是SurfaceView的子類,openGL專用。

  在2D遊戲開發中,大致可以分爲兩種遊戲框架,View和SurfaceView。 View和SurfaceView區別:

  View:必須在UI的主線程中更新畫面,用於被動更新畫面。

  surfaceView:UI線程和子線程中都可以。在一個新啓動的線程中重新繪製畫面,主動更新畫面。

UI的主線程中更新畫面可能會引發問題,比如你更新畫面的時間過長,那麼你的主UI線程會被你正在畫的函數阻塞。那麼將無法響應按鍵,觸屏等消息。
當使用surfaceView 由於是在新的線程中更新畫面所以不會阻塞你的UI主線程。但這也帶來了另外一個問題,就是事件同步,涉及到線程同步。

所以基於以上,根據遊戲特點,一般分成兩類。

1 被動更新畫面的。比如棋類,這種用view就好了。因爲畫面的更新是依賴於 onTouch 來更新,可以直接使用 invalidate。 因爲這種情況下,這一次Touch和下一次的Touch需要的時間比較長些,不會產生影響。

2 主動更新。比如一個人在一直跑動。這就需要一個單獨的thread不停的重繪人的狀態,避免阻塞main UI thread。所以顯然view不合適,需要surfaceView來控制。

下面是使用sufaceView一個基本的框架:

import android.app.Activity;  
import android.content.Context;  
import android.graphics.Canvas;  
import android.graphics.Color;  
import android.graphics.Paint;  
import android.os.Bundle;  
import android.view.SurfaceHolder;  
import android.view.SurfaceView;  

public class TestSurfaceView extends Activity {  
    /** Called when the activity is first created. */  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(new MyView(this));  
    }  

    class MyView extends SurfaceView implements SurfaceHolder.Callback,Runnable{  
        SurfaceHolder holder=null;  
        Paint paint;  
        public MyView(Context context) {  
            super(context);  
            // TODO Auto-generated constructor stub  
            holder=getHolder();  
            holder.addCallback(this);  
            paint=new Paint(Paint.ANTI_ALIAS_FLAG);  
            paint.setColor(Color.RED);  

            this.setFocusable(true);  
        }  

        @Override  
        public void surfaceChanged(SurfaceHolder holder, int format, int width,  
                int height) {  
            // TODO Auto-generated method stub  

        }  

        @Override  
        public void surfaceCreated(SurfaceHolder holder) {  
            // TODO Auto-generated method stub  
            Thread t=new Thread(this);  
            t.start();  
        }  

        @Override  
        public void surfaceDestroyed(SurfaceHolder holder) {  
            // TODO Auto-generated method stub  
            isRunning=false;  
        }  

        @Override  
        protected void onDraw(Canvas canvas) {  
            // TODO Auto-generated method stub  
            canvas=holder.lockCanvas();  
            //刷屏    
            canvas.drawColor(Color.BLACK);  

            canvas.drawCircle(x, y, 10, paint);  

            holder.unlockCanvasAndPost(canvas);  
        }  
        private void paint(Paint paint) {  
            Canvas canvas=holder.lockCanvas();  
            //刷屏    
            canvas.drawColor(Color.BLACK);  

            canvas.drawCircle(x, y, 10, paint);  

            holder.unlockCanvasAndPost(canvas);  
        }  

        boolean isRunning=true;  
        @Override  
        public void run() {  
            // TODO Auto-generated method stub  
            while (isRunning) {  
//              onDraw(null);  
                paint(paint);  
                move();  
                try {  
                    Thread.sleep(50);  
                } catch (InterruptedException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  

            }  
        }  

        private int x,y;  
        private void move(){  
            x+=2;  
            y+=2;  
        }  
    }  

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章