網上的一篇心得,收藏先。
1 AndEngine原理:
解讀AndEngine源碼後我們可以發現,AndEngine除了采取低耦合、高内聚的架構政策細分引擎子產品,使用OpenGLES進行遊戲渲染之外;該引擎還以雙線程方式分别驅動繪圖與事務更新,事實上,它将遊戲畫面和遊戲業務分為兩組邏輯,并行跑在同級的互斥線程當中。
具體地說,其繪圖線程位于AndEngine提供的GLSurfaceView内部類GLThread(在AndEngine的org.anddev.andengine.opengl.view包下,非Android預設的GLSurfaceView),并通過GLSurfaceView子類,即AndEngine提供的RenderSurfaceView類調用重載的onDrawFrame函數加以渲染控制;而業務線程在Engine類的内部類UpdateThread中,AndEngine将始終以while(true)這樣的死循環方式快速執行其中的onTickUpdate函數,所有AndEngine提供的遊戲業務最終都會由此函數調用及執行,比如AndEngine常用的registerUpdateHandler方法就是向它送出資料。
當AndEngine進行遊戲繪圖時,遊戲業務線程會通過wait方式鎖定,而當遊戲業務處理時,也會以同樣的手段鎖定繪圖線程,二者間具體互動關系由Engine類中的State子類控制,以此保證遊戲畫面與遊戲業務同步。
另外,或許是考慮到持續雙線程運作電量消耗較大的緣故,AndEngine預設情況下要求使用者啟動PowerManager進行電源管理,故此需要<uses-permission android:name="android.permission.WAKE_LOCK"/>權限支援,否則初始化時Log會提示缺少相關配置,并建議你在AndroidManifest.xml中添權重限。PS:無此權限不影響運作,隻會在Log有警告資訊,并且耗電較快。
1.2 AndEngine的基本運作流程:
由于AndEngine是專供Android使用的2D遊戲引擎,是以作為啟動類的Activity肯定必不可少,而AndEngine也理所應當的提供給我們這樣一個Activity,那就是BaseGameActivity。
一個标準的AndEngine應用,至少應該對BaseGameActivity做繼承:
其中四個必須被重載函數的啟動順序如下:
onLoadEngine->onLoadResources->onLoadScene->onLoadComplete
具體的講,AndEngine會首先加載Engine類執行個體通知系統遊戲引擎的基本運作方式,而後加載遊戲資源,其次加載遊戲場景執行個體,最後通過onLoadComplete通知使用者加載完畢并于此進行善後工作。
此外,由于BaseGameActivity類重載了父類Activity的onResume與onPause函數以保證其自身的正常運作,是以不建議在繼承BaseGameActivity時再次重載上述函數(重載的話不要忘記super調用),推薦直接重載AndEngine提供的onGamePaused和onGameResumed實作同等功能(最近把LGame也加上了這樣的兩個函數,并且禁止了LGameAndroid2DActivity子類重載onResume與onPause,務求減少使用者錯誤重載導緻的程式異常)。
1.3 AndEngine的基本運作方式:
上文介紹了AndEngine的基本運作機制與運作流程,然而僅僅這樣AndEngine還是無法實際運作,因為Engine與Scene都沒有獲得具體實作。假如我們想要在螢幕上顯示出目前應用FPS數,至少需要做些改動,才能滿足一個最為基本的AndEngine應用:
另外,事實上BaseGameActivity并非AndEngine提供的唯一Activity,其UI包下尚有以SplashScene場景作為特效啟動的BaseSplashActivity類,以及通過重載getLayoutID與getRenderSurfaceViewID這兩個抽象函數,調用指定布局與視圖的LayoutGameActivity類。不過除了上述特點,它們與BaseGameActivity就再無差別了。
二、如何使用AndEngine中的常用功能:
事實上,AndEngine中元件顆粒都非常細小,幾乎每個由AndEngine提供的功能都會有一個對應的類存在;AndEngine将許多很小很小的功能,做成了太多太多的子產品。比如僅Engine就衍生出DoubleSceneSplitScreenEngine(可以同時顯示并緩存兩個Scene的Engine,通過setFirstScene以及setSecondScene進行雙屏切換,即分屏用Engine)、SingleSceneSplitScreenEngine(與DoubleSceneSplitScreenEngine類似,但一次隻能顯示一個畫面)、LimitedFPSEngine(可限制FPS速度的Engine,重載了标準Engine的onUpdate函數,減速方式為常見的線程延遲)、FixedStepEngine(與LimitedFPSEngine近似,重載了标準Engine的onUpdate函數,但是它通過反複while方式最大限度矯正AndEngine内部計時器的累加數值,以求每次線程主循環的幀數都與預想幀數相等)等許多子類(目前細分還在不斷增加)。其實,這些功能完全可以進行統一實作,而不必占據那麼的應用空間與使用者記憶細胞。
2.1 AndEngine的IUpdateHandler接口:
IUpdateHandler類是AndEngine引擎中使用頻率非常之高的元件之一,其本身是一個接口,内部有onUpdate以及reset兩個函數等待實作,幾乎所有AndEngine應用中都必然會看到它的身影,它也是AndEngine添加具體業務到遊戲業務線程中的主要方法之一。
具體的講,所有通過AndEngine中registerUpdateHandler函數注冊的IUpdateHandler,都會被儲存到一個叫做UpdateHandlerList的IUpdateHandler接口集合當中。雖然UpdateHandlerList本身也是一個IUpdateHandler接口的實作,然而它的地位卻比較特殊,基本隻存在于Engine及Scene類中,并隻供Engine類中的onTickUpdate函數調用,每當AndEngine業務線程循環onTickUpdate這個Engine内部方法時,都會調用UpdateHandlerList中存在的所有IUpdateHandler,直到登出相關的IUpdateHandler執行個體為止。
另外,與UpdateHandlerList集合類作用類似的還有RunnableHandler類,該類同樣是IUpdateHandler的具體實作,它的作用在于儲存并執行一次标準Runnable(每次業務循環後都會清空RunnableHandler的内部資料)。該類在AndEngine業務線程中的執行時機略早于UpdateHandlerList,我們可以通過RunnableHandler類中的postRunnable函數,或Engine類中的runOnUpdateThread函數添加Runnable到該集合(runOnUpdateThread函數為postRunnable函數的調用封裝,Engine類及相關子類,BaseGameActivity類及相關子類中可見)。
2.2 AndEngine的Async方法:
預設情況下,AndEngine的資源加載會在建構Engine之後,調用onLoadResources函數時進行同步加載。但如果一次性加載資源太多時,便可能會面臨一個問題,那就是Android系統将自動關閉長期無響應的UI。是以一旦采取同步執行的加載政策,資料量過大時就有可能将我們的APK卡死。是以,這就需要異步加載政策來解決問題,而AndEngine也确實提供了我們這樣的異步加載方式。
具體的講,AndEngine對Android系統自帶的AsyncTask類進行了适當封裝(具體封裝在BaseActivity類中,該類為BaseGameActivity的父類,AndEngine由此類開始實際繼承Activity,但BaseGameActivity的主要功能并不在此類),隻要通過doAsync或者doProgressAsync函數就可以調用。
2.3 AndEngine中的精靈調用:
精靈類,是一個大家耳熟能詳,并且任何遊戲引擎無法回避的關鍵性元件之一,它常常被用來表示一個遊戲中角色或者特定畫面要素。如此重要的存在,AndEngine當然也不能缺少。
2.3 AndEngine的精靈動畫:
在絕大多數的遊戲開發中,僅僅有精靈類存在是并不足夠的,我們往往還需要讓精靈作出絢麗的效果以吸引使用者眼球,而這些效果在AndEngine中,統一通過它所提供的各個Modifier類進行實作。
1、關于Engine:
Engine是AndEngine的核心所在,它對AndEngine引擎中Camera、Scene等重要元件進行了統一管理,但必須和BaseGameActivity合作使用,利用EngineOptions類可以對其進行必要的參數配置。
2、關于BaseGameActivity:
如果您想正常使用AndEngine,那麼目前Activity就必須繼承自BaseGameActivity或其子類,否則你連初始化Engine也做不到。雖然它還有父類BaseActivity,但BaseActivity隻提供了一些異步加載方法而無關AndEngine的主體實作。是以,BaseGameActivity就是實際上的AndEngine最基礎用類無疑。
3、關于IResolutionPolicy:
IResolutionPolicy是一個接口類,其中隻規定了onMeasure函數的實作格式。事實上,AndEngine中所有該類具體實作的作用與标準View中的onMeasure函數幾乎一緻,也會被标準View中的onMeasure函數重載調用(具體調用在AndEngine的RenderSurfaceView類當中)。而且除BaseResolutionPolicy外,所有AndEngine的IResolutionPolicy實作也都調用了View的setMeasuredDimensionProxy函數。
在AndEngine的org.anddev.andengine.engine.options.resolutionpolicy包下有一組IResolutionPolicy接口的具體實作,分别為BaseResolutionPolicy(除了會校驗一下螢幕大小外,什麼也不做)、FillResolutionPolicy(拉伸遊戲畫面為全屏填充,視錄影機大小不同,會有不同程度變形)、FixedResolutionPolicy(強行規定遊戲畫面為固定大小,此設定不會自動适應螢幕大小),RatioResolutionPolicy(按比例修正畫面大小,以适應螢幕大小),RelativeResolutionPolicy(根據建構RelativeResolutionPolicy時的縮放參數,縮放遊戲螢幕為指定比例)。
最後,所有IResolutionPolicy的實作類,都要随着EngineOptions于初試化時傳遞給Engine執行個體才起作用。
4、關于Camera:
該類即我們常說的遊戲錄影機,在AndEngine的Camera有兩種作用,一是用以調節螢幕的顯示區域,二是利用HUD類實際繪制遊戲螢幕于手機之上。
5、關于Scene:
場景容器,作用類似于LGame中的Screen,能夠将某一特定場景作為遊戲子產品進行調用,我們可以利用它來切換目前遊戲的畫面與觸摸屏監聽,切換方法是利用Engine.setScene。
6、關于Entity:
Entity是IEntity接口的具體實作,也是AndEngine中無論Scene、Layer、Sprite(這個繼承關系比較遠,中間隔了BaseRectangle、RectangularShape、GLShape、Shape等上級類,不過追溯源頭始終繼承自Entity)的統一父類,通過Entity我們可以讓AndEngine中場景,或場景中某精靈實作統一效果的縮放、旋轉、變色等操作。
7、關于Texture:
Texture是AndEngine所提供的紋理用類,但Texture本身(在AndEngine中)并沒有提供加載圖檔的方法,必須通過TextureRegionFactory類(更準确的說,依賴它内部封裝的TextureRegion、BuildableTexture等類)與之合作才可以加載紋理。除此之外,AndEngine要求所加載紋理(圖檔)大小必須為2的整數次幂。
8、關于TextureRegion:
TextureRegion的父類是抽象類BaseTextureRegion,主要功能也被封裝在BaseTextureRegion類當中,AndEngine提供了TextureRegionFactory這個工廠類用以簡化建構TextureRegion的流程。單就TextureRegion來講,它的作用似乎就是讓系統知道如何剪切一個紋理,并傳回一個這樣的紋理給你。
然而,事實上AndEngine中隻有TextureRegion才更接近于通常意義上的Texture。或者說,隻有TextureRegion + Texture時,我們才能較為完整的使用AndEngine紋理功能。嚴肅的講,AndEngine中的Texture有很多功能必須靠TextureRegion最終完成,比如AndEngine中的Sprite必須加載TextureRegion才能使用Texture,而不是直接調用Texture,TMXTiledMap中讀取指定瓦片傳回的也是TextureRegion,而非直接的Texture(進行畫面渲染時AndEngine内部會調用TextureRegion中的Texture引用,但也隻允許如此調用);應該說,AndEngine中見Texture幾乎必見TextureRegion,二者無法分離,缺一不可。
9、關于TextureOptions
在AndEngine中,TextureRegionFactory類決定紋理的加載路徑,Texture類作為承載紋理的實體對象,而TextureOptions類決定了紋理的渲染方式。
也即是說,OpenGLES将以何種方式顯示紋理圖像,都由TextureOptions類所決定。在目前最新版本的AndEngine中,預設提供了:
1、NEAREST(Nearest濾波,實作上依賴GL_NEAREST做不光滑過濾,紋理環繞模式為GL_CLAMP_TO_EDGE,顯示速度快畫質差)
2、BILINEAR(雙線性插值,實作上依賴GL_LINEAR做線性濾波,紋理環繞模式為GL_CLAMP_TO_EDGE,顯示速度慢畫質佳)
3、REPEATING(與NEAREST同為Nearest濾波,但紋理環繞模式為GL_REPEAT,會自動填充紋理上的空白區域,顯示速度較快畫質差)
4、REPEATING_BILINEAR(與BILINEAR同為雙線性插值,但紋理環繞模式為GL_REPEAT,會自動填充紋理上的空白區域,顯示速度很慢畫質佳(低端機跑此模式異常悲劇,高端機尚可))
5、NEAREST_PREMULTIPLYALPHA(所有[PREMULTIPLYALPHA]結尾的TextureOptions與其它同名類差别僅在于是否支援根據Alpha值設定透明紋理,以下同)
6、BILINEAR_PREMULTIPLYALPHA
7、REPEATING_PREMULTIPLYALPHA
8、REPEATING_BILINEAR_PREMULTIPLYALPHA等靜态對象。
這個是網上的一些學習心得,先收藏着。
本文轉自xuzw13 51CTO部落格,原文連結:http://blog.51cto.com/xuzhiwei/1049074,如需轉載請自行聯系原作者