- Android游戲開發(fā)技術實戰(zhàn)詳解
- 褚尚軍 張加春編著
- 99字
- 2018-12-30 05:33:19
3.5 游戲框架
大多數(shù)知名企業(yè)的游戲都是基于Apache Struts、Spring和Hibernate等開發(fā)框架的。這些框架都是基于MVC設計模式的,實現(xiàn)了業(yè)務和邏輯的分離,這已經(jīng)成為當前游戲開發(fā)的主流模式。本節(jié)將簡單分析Android平臺提供的View和Surfaceview類的基本知識。
3.5.1 View類
View視圖類是Android系統(tǒng)中的一個超類,在此類中幾乎包含了所有的屏幕類型。每一個View都有一個用于繪圖的畫布,這個畫布可以進行任意擴展。在游戲開發(fā)中也可以自定義View視圖,這個畫布的功能更能滿足我們在游戲開發(fā)中的需要。
在Android系統(tǒng)中,任何一個View類都只需重寫onDraw()方法來實現(xiàn)界面顯示,自定義的視圖可以是復雜的3D實現(xiàn),也可以是非常簡單的文本形式。
在游戲中最重要的就是與玩家的交互,例如,鍵盤輸入、觸筆點擊事件如何來處理呢?在Android中提供了onKeyUp、onKeyDown、onKeyMultiple、onKeyPreIme、onTouchEvent和onTrackballEvent等方法,通過這些方法可以輕松處理游戲中的事件信息。在繼承View時需要重載這幾個方法,當有按鍵按下或彈起事件發(fā)生時,按鍵代碼自動會傳輸給這些相應的方法來處理。
游戲的核心功能是不斷繪圖和刷新界面,視圖可以通過onDraw()方法繪制,接下來重點分析如何刷新界面。在Android中提供了invalidate()方法來刷新界面。不能直接在線程中調用方法invalidate(),特別是不能在子線程中調用,因為這違背了Android單線程模型。Android UI操作并不是線程安全的,并且這些操作必須在UI線程中執(zhí)行,因此Android中最常用的方法就是利用Handler來實現(xiàn)UI線程的更新。
接下來通過一個具體實例,介紹在Android中使用View類實現(xiàn)屏幕更新顯示的方法。
實例3-13 使用View類(daima\3\ViewC)。
在本實例中,要在屏幕上繪制了一個不停變換顏色的矩形,并且定義一些事件來通過模擬器的上下鍵調節(jié)矩形的位置(比如把這個矩形向上移動或者把這個矩形向下移動)。本實例的實現(xiàn)文件是ViewC.java,主要代碼如下所示。
public class ViewC extends View { int miCount = 0; int y = 0; public ViewC(Context context) { super(context); } // //繪圖處理 public void onDraw(Canvas canvas) { if (miCount < 100) { miCount++; } else { miCount = 0; } //繪圖 Paint mPaint = new Paint(); switch (miCount%4) { case 0: mPaint.setColor(Color.BLUE); break; case 1: mPaint.setColor(Color.GREEN); break; case 2: mPaint.setColor(Color.RED); break; case 3: mPaint.setColor(Color.YELLOW); break; default: mPaint.setColor(Color.WHITE); break; } //繪制矩形--后面將詳細講解 canvas.drawRect((320-80)/2, y, (320-80)/2+80, y+40, mPaint); } }
執(zhí)行后將在屏幕內(nèi)繪制一個矩形,并隨著線程的變化矩形的填充顏色隨之變化,從而實現(xiàn)閃爍效果,如圖3-35所示。通過鍵盤上的上下鍵來移動矩形,如圖3-36所示。

圖3-35 閃爍效果

圖3-36 上下移動矩形
3.5.2 SurfaceView類
類SurfaceView在游戲開發(fā)中有著舉足輕重的作用,它對畫面的控制有更大的自由度。SurfaceView類有個雙緩沖機制,在開發(fā)游戲時經(jīng)常用到,提高整個效率。
1. SurfaceView類基礎
在Android中開發(fā)游戲時,一般來說,要想寫一個復雜一點的游戲,必須使用SurfaceView來實現(xiàn)。SurfaceView可直接訪問一個可畫圖的界面,可以控制在界面頂部的子視圖層。SurfaceView是提供給需要直接畫像素而不是使用窗體部件的應用使用的。Android圖形系統(tǒng)中的一個重要的概念和線索是Surface(界面)、View(視圖)及其子類,如TextView和Button。
要想在Surface上繪圖。則必須為每個Surface創(chuàng)建一個Canvas對象(但屬性時常改變),用來管理View在Surface上的繪圖操作,如畫點與畫線。還要注意的是,在使用SurfaceView的時候,一般都是出現(xiàn)在最頂層。
在使用SurfaceView的時候,一般情況下還要對創(chuàng)建、銷毀、改變時的情況進行監(jiān)視,格式如下所示。
//在 surface的大小發(fā)生改變時激發(fā) public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){} //在創(chuàng)建時激發(fā),一般在這里調用畫圖的線程 public void surfaceCreated(SurfaceHolder holder){} //銷毀時激發(fā),一般在這里將畫圖的線程停止、釋放 public void surfaceDestroyed(SurfaceHolder holder) {}
surfaceCreated會首先被調用,然后是surfaceChanged,當程序結束時會調用surfaceDestroyed。
由于SurfaceHolder是一個共享資源,所以在對其操作時應該實行“互斥操作”,即需要使用synchronized的“封鎖”機制。
渲染文字的工作實際上是主線程(也就是LunarView類)的父類View的工作,而并不屬于工作線程LunarThread,在工作線程中是無法控制的,所以改為向主線程發(fā)送一個Message來代替,讓主線程通過Handler對接收到的消息進行處理,從而更新界面文字信息。
接下來將通過一個具體的實例,介紹在Android中使用SurfaceView類實現(xiàn)屏幕更新顯示的流程。
實例3-14 使用SurfaceView類實現(xiàn)屏幕內(nèi)容的閃爍顯示(daima\3\SurfaceC)。
本實例的實現(xiàn)文件是SurfaceC.java,具體代碼如下所示。
package com.SurfaceC; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.SurfaceHolder; import android.view.SurfaceView; public class SurfaceC extends SurfaceView implements SurfaceHolder.Callback,Runnable { //控制循環(huán) boolean mbLoop = false; //定義SurfaceHolder對象 SurfaceHolder mSurfaceHolder = null; int miCount = 0; int y = 50; public SurfaceC(Context context) { super(context); //實例化SurfaceHolder mSurfaceHolder = this.getHolder(); //添加回調 mSurfaceHolder.addCallback(this); this.setFocusable(true); mbLoop = true; } //在surface的大小發(fā)生改變時激發(fā) public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } //在surface創(chuàng)建時激發(fā) public void surfaceCreated(SurfaceHolder holder) { //開啟繪圖線程 new Thread(this).start(); } //在surface銷毀時激發(fā) public void surfaceDestroyed(SurfaceHolder holder) { //停止循環(huán) mbLoop = false; } //繪圖循環(huán) public void run() { while (mbLoop) { try { Thread.sleep(200); } catch (Exception e) { } synchronized( mSurfaceHolder ) { Draw(); } } } //繪圖方法 public void Draw() { //鎖定畫布,得到canvas Canvas canvas= mSurfaceHolder.lockCanvas(); if (mSurfaceHolder==null || canvas == null ) { return; } if (miCount < 100) { miCount++; } else { miCount = 0; } //繪圖 Paint mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(Color.BLACK); //繪制矩形--清屏作用 canvas.drawRect(0, 0, 320, 480, mPaint); switch (miCount % 4) { case 0: mPaint.setColor(Color.BLUE); break; case 1: mPaint.setColor(Color.GREEN); break; case 2: mPaint.setColor(Color.RED); break; case 3: mPaint.setColor(Color.YELLOW); break; default: mPaint.setColor(Color.WHITE); break; } // 繪制矩形--后面將詳細講解 canvas.drawCircle((320 - 25) / 2, y, 50, mPaint); // 繪制后解鎖,繪制后必須解鎖才能顯示 mSurfaceHolder.unlockCanvasAndPost(canvas); } }
執(zhí)行后將在屏幕內(nèi)繪制一個圓形,并隨著線程的變化,圓形的填充顏色也隨之變化,從而實現(xiàn)閃爍效果,如圖3-37所示;可以通過鍵盤上的上下鍵來移動圓形,如圖3-38所示。

圖3-37 閃爍效果

圖3-38 上下移動圓形
2. 雙緩沖
雙緩沖的是一種防止動畫閃爍的多線程應用,基于SurfaceView的雙緩沖實現(xiàn)很簡單,只需開一條線程并在其中繪圖即可。Android中的SurfaceView類就基于雙緩沖機制,所以在開發(fā)游戲時應盡量使用SurfaceView而不要使用View,這樣效率會較高,而且SurfaceView的功能也更加完善。
雙緩沖的核心是先通過方法setBitmap()將要繪制的所有圖形繪制到一個Bitmap(圖像對象)上,然后調用方法drawBitmap()繪制這個Bitmap,并在屏幕上顯示出來。下面將通過一個具體的實例,講解在Android中使用SurfaceView類實現(xiàn)雙緩沖。
實例3-15 使用雙緩沖技術在屏幕中顯示一幅圖片(daima\3\shuanghuan)。
本實例的實現(xiàn)文件是shuanghuan.java,具體代碼如下所示。
package com.shuanghuan; import com.shuanghuan.R; import Android.content.Context; import Android.graphics.Bitmap; import Android.graphics.Canvas; import Android.graphics.Paint; import Android.graphics.Bitmap.Config; import Android.graphics.drawable.BitmapDrawable; import Android.view.KeyEvent; import Android.view.MotionEvent; import Android.view.View; public class shuanghuan extends View implements Runnable { /* 聲明Bitmap對象 */ Bitmap mBitQQ = null; Paint mPaint = null; /* 創(chuàng)建一個緩沖區(qū) */ Bitmap mSCBitmap = null; /* 創(chuàng)建Canvas對象 */ Canvas mCanvas = null; public shuanghuan(Context context) { super(context); /* 裝載資源 */ mBitQQ = ((BitmapDrawable) getResources().getDrawable(R.drawable.qq)).getBitmap(); /* 創(chuàng)建屏幕大小的緩沖區(qū) */ mSCBitmap=Bitmap.createBitmap(320, 480, Config.ARGB_8888); /* 創(chuàng)建Canvas */ mCanvas = new Canvas(); /* 設置將內(nèi)容繪制在mSCBitmap上 */ mCanvas.setBitmap(mSCBitmap); mPaint = new Paint(); /* 將mBitQQ繪制到mSCBitmap上 */ mCanvas.drawBitmap(mBitQQ, 0, 0, mPaint); /* 開啟線程 */ new Thread(this).start(); } public void onDraw(Canvas canvas) { super.onDraw(canvas); /* 將mSCBitmap顯示到屏幕上 */ canvas.drawBitmap(mSCBitmap, 0, 0, mPaint); } //觸筆事件 public boolean onTouchEvent(MotionEvent event) { return true; } //按鍵按下事件 public boolean onKeyDown(int keyCode, KeyEvent event) { return true; } //按鍵彈起事件 public boolean onKeyUp(int keyCode, KeyEvent event) { return false; } public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { return true; } /*線程處理*/ public void run() { while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } //使用postInvalidate可以直接在線程中更新界面 postInvalidate(); } } }
執(zhí)行后將用雙緩沖技術在屏幕中顯示圖片,效果如圖3-39所示。

圖3-39 執(zhí)行效果
- 智慧城市:大數(shù)據(jù)、互聯(lián)網(wǎng)時代的城市治理(第4版)
- 數(shù)據(jù)通信網(wǎng)絡實踐:基礎知識與交換機技術
- RCNP實驗指南:構建高級的路由互聯(lián)網(wǎng)絡(BARI)
- 網(wǎng)絡協(xié)議工程
- Mastering Machine Learning for Penetration Testing
- INSTANT PhpStorm Starter
- 物聯(lián)網(wǎng)安全與深度學習技術
- Force.com Development Blueprints
- NB-IoT物聯(lián)網(wǎng)技術解析與案例詳解
- SSL VPN : Understanding, evaluating and planning secure, web/based remote access
- Mastering TypeScript 3
- Microsoft Dynamics CRM 2011 Applications(MB2-868) Certification Guide
- 語音信號處理及Blackfin DSP實現(xiàn)
- 圖神經(jīng)網(wǎng)絡前沿
- 現(xiàn)場綜合化網(wǎng)絡運營與維護:運營商數(shù)字化轉型技術與實踐