Android 遊戲開發(二)SurfaceView初探

來源:互聯網
上載者:User

標籤:des   android   style   blog   color   os   使用   io   for   

SurfaceView遊戲架構在遊戲開發當中有舉足輕重的地位。
SurfaceHolder類是用來控制SurfaceView的大小、格式,並且主要用於監聽Surface的狀態。
SurfaceView好像就是一塊記憶體資料裡面記錄著資料,更改資料而是由SurfaceHolder來控制,使用SurfaceHolder的lockCanvas()函數來擷取SurfaceView的Canvas對象。然後在Canvas上繪製內容來修改SurfaceView中的資料。

 

import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;public class MySurfaceView extends SurfaceView implements Callback {    //該類主要是用來監聽SurfaceView的狀態    private SurfaceHolder holder;    private Paint paint;        public MySurfaceView(Context context) {        super(context);        holder = this.getHolder();        //為Surface添加監聽狀態        holder.addCallback(this);        //執行個體一隻畫筆        paint = new Paint();        //將畫筆設定為白色        paint.setColor(Color.WHITE);    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        myDraw();    }    @Override    public void surfaceDestroyed(SurfaceHolder arg0) {    }    private void myDraw() {        //lockCanvas不僅僅是得到Canvas,並且對Canvas加鎖        //防止在繪製過程中遭到破壞        Canvas mCanvas = holder.lockCanvas();        mCanvas.drawText("Game", 50, 10, paint);        holder.unlockCanvasAndPost(mCanvas);    }        @Override    protected void onDraw(Canvas canvas) {        canvas.drawText("Game", 50, 50, paint);        super.onDraw(canvas);    }}

 

在SurfaceView中重載的onDraw()方法並不會執行,更加能夠說明了SurfaceView是通過SurfaceHolder來修改資料的,所以SurfaceView即使重寫了onDraw()方法也不會執行到。接下來重複上一次View的操作,重寫onTouchEvent()方法。

@Overridepublic boolean onTouchEvent(MotionEvent event) {    posX = (int) event.getX();    posY = (int) event.getY();    myDraw();    return true;}

 

發現重寫onTouchEvent()方法後,螢幕繪製變得亂七八糟。跟上一次重寫後的效果完全不一樣。其主要原因是畫布沒有重新整理,將每次繪製的文本全部都顯示了出來。解決方案就是對畫布進行“刷屏”。

private void myDraw() {    Canvas mCanvas = holder.lockCanvas();    //就是在重繪之前用一張背景,將原來的覆蓋掉    paint.setColor(Color.BLACK);    mCanvas.drawRect(0, 0, this.getWidth(), this.getHeight(), paint);    paint.setColor(Color.WHITE);    mCanvas.drawText("Game", posX, posY, paint);    holder.unlockCanvasAndPost(mCanvas);}


SurfaceView視圖添加線程
在遊戲中,基本上不會等使用者觸發了某個事件才去重繪畫布,而是一個較短的固定周期去重繪畫布;比如動態花花草草,流水等情境,這些遊戲元素並不會跟玩家進行互動。但是這些元素都是動態。所以遊戲開發中,都會有一個線程不停的去重新繪製。

import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;public class MySurfaceView extends SurfaceView implements Callback , Runnable{    //該類主要是用來監聽SurfaceView的狀態    private SurfaceHolder holder;    private Paint paint;    private int posX = 100;    private int posY = 100;    private int flag;    private Canvas canvas;    private int screenW, screenH;        public MySurfaceView(Context context) {        super(context);        holder = this.getHolder();        //為Surface添加監聽狀態        holder.addCallback(this);        //執行個體一隻畫筆        paint = new Paint();            //將畫筆設定為白色        paint.setColor(Color.WHITE);        paint.setTextSize(50f);        //設定焦點        setFocusable(true);    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        screenH = this.getHeight();        screenW = this.getWidth();        flag = 1;        new Thread(this).start();    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        flag = 0;    }    private void myDraw() {        try {            canvas = holder.lockCanvas();            if(canvas!=null){                //就是在重繪之前用一張背景,將原來的覆蓋掉                paint.setColor(Color.BLACK);                canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), paint);                paint.setColor(Color.WHITE);                canvas.drawText("Game", posX, posY, paint);            }        } catch (Exception e) {        }finally{            if(canvas!=null){                holder.unlockCanvasAndPost(canvas);            }        }    }        @Override    public boolean onTouchEvent(MotionEvent event) {        posX = (int) event.getX();        posY = (int) event.getY();        myDraw();        return true;    }    private void logic(){}//遊戲邏輯    @Override    public void run() {        while(flag==1){            long start = System.currentTimeMillis();            myDraw();            logic();            long end = System.currentTimeMillis();            try {                //保證重繪的最小周期是50                if(end - start < 50){                    Thread.sleep(50 - (end -start));                }            } catch (InterruptedException e) {            }        }    }}

 

一般遊戲的重新整理時間是50-100毫秒,也就是每秒10-20幀左右。

最後感謝百度、感謝《遊戲編程之從0開始》。

 

Android 遊戲開發(二)SurfaceView初探

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.