項(xiàng)目站點(diǎn):
http://www.andengine.org
項(xiàng)目地址:
http://code.google.com/p/andengine
示例地址:
http://code.google.com/p/andengineexamples
PS:本文中使用的AndEngine源碼為2011年3月3日獲得。
AndEngine是一款以O(shè)penGLES方式進(jìn)行畫面渲染的2D游戲引擎,可以運(yùn)行在支持Android 1.6及以上版本的系統(tǒng)當(dāng)中。應(yīng)該說(shuō),相較前文介紹的Libgdx引擎,AndEngine擁有更多的游戲組件與擴(kuò)展功能。并且與Libgdx不同,它在默認(rèn)情況下已經(jīng)可以支持中文,采用屏幕坐標(biāo)系繪也更符合一般Android繪圖習(xí)慣。
然而,有其利也必有其弊,AndEngine作為游戲引擎雖然在功能上較Libgdx更為豐富也更人性化,但相比Libgdx的繪圖渲染機(jī)能卻遜色不少(粗讀源碼可以發(fā)現(xiàn),Libgdx有較為完善的OpenGLES環(huán)境適應(yīng)性,而AndEngine在這方面的投入明顯不足)。事實(shí)上,市井也一直有流言說(shuō)AndEngine引擎在不同手機(jī)機(jī)型上的表現(xiàn)并不穩(wěn)定(詳見:
http://www.badlogicgames.com/wordpress/?p=816
與
http://www.badlogicgames.com/wordpress/?p=803
,Libgdx作者M(jìn)ario所寫)。
所以,您是否選擇AndEngine引擎,還是應(yīng)該從實(shí)際出發(fā),多做真機(jī)測(cè)試才好下決定。下面開始,我將逐步講解一些有關(guān)AndEngine引擎的基礎(chǔ)信息。
AndEngine引擎基礎(chǔ)構(gòu)成如下圖所示:
一、如何使用AndEngine:
1.1 AndEngine的基本運(yùn)行原理:
解讀AndEngine源碼后我們可以發(fā)現(xiàn),AndEngine除了采取低耦合、高內(nèi)聚的框架策略細(xì)分引擎模塊,使用OpenGLES進(jìn)行游戲渲染之外;該引擎還以雙線程方式分別驅(qū)動(dòng)繪圖與事務(wù)更新,事實(shí)上,它將游戲畫面和游戲業(yè)務(wù)分為兩組邏輯,并行跑在同級(jí)的互斥線程當(dāng)中。
具體地說(shuō),其繪圖線程位于AndEngine提供的GLSurfaceView內(nèi)部類GLThread(在AndEngine的org.anddev.andengine.opengl.view包下,非Android默認(rèn)的GLSurfaceView),并通過GLSurfaceView子類,即AndEngine提供的RenderSurfaceView類調(diào)用重載的onDrawFrame函數(shù)加以渲染控制;而業(yè)務(wù)線程在Engine類的內(nèi)部類UpdateThread中,AndEngine將始終以while(true)這樣的死循環(huán)方式快速執(zhí)行其中的onTickUpdate函數(shù),所有AndEngine提供的游戲業(yè)務(wù)最終都會(huì)由此函數(shù)調(diào)用及執(zhí)行,比如AndEngine常用的registerUpdateHandler方法就是向它提交數(shù)據(jù)。
當(dāng)AndEngine進(jìn)行游戲繪圖時(shí),游戲業(yè)務(wù)線程會(huì)通過wait方式鎖定,而當(dāng)游戲業(yè)務(wù)處理時(shí),也會(huì)以同樣的手段鎖定繪圖線程,二者間具體交互關(guān)系由Engine類中的State子類控制,以此保證游戲畫面與游戲業(yè)務(wù)同步。
另外,或許是考慮到持續(xù)雙線程運(yùn)行電量消耗較大的緣故,AndEngine默認(rèn)情況下要求用戶啟動(dòng)PowerManager進(jìn)行電源管理,故此需要<uses-permission android:name="android.permission.WAKE_LOCK"/>權(quán)限支持,否則初始化時(shí)Log會(huì)提示缺少相關(guān)配置,并建議你在AndroidManifest.xml中添加權(quán)限。PS:無(wú)此權(quán)限不影響運(yùn)行,只會(huì)在Log有警告信息,并且耗電較快。
1.2 AndEngine的基本運(yùn)行流程:
由于AndEngine是專供Android使用的2D游戲引擎,所以作為啟動(dòng)類的Activity肯定必不可少,而AndEngine也理所應(yīng)當(dāng)?shù)奶峁┙o我們這樣一個(gè)Activity,那就是BaseGameActivity。
一個(gè)標(biāo)準(zhǔn)的AndEngine應(yīng)用,至少應(yīng)該對(duì)BaseGameActivity做如下繼承:
其中四個(gè)必須被重載函數(shù)的啟動(dòng)順序如下:
onLoadEngine->onLoadResources->onLoadScene->onLoadComplete
具體的講,AndEngine會(huì)首先加載Engine類實(shí)例通知系統(tǒng)游戲引擎的基本運(yùn)行方式,而后加載游戲資源,其次加載游戲場(chǎng)景實(shí)例,最后通過onLoadComplete通知用戶加載完畢并于此進(jìn)行善后工作。
此外,由于BaseGameActivity類重載了父類Activity的onResume與onPause函數(shù)以保證其自身的正常運(yùn)行,所以不建議在繼承BaseGameActivity時(shí)再次重載上述函數(shù)(重載的話不要忘記super調(diào)用),推薦直接重載AndEngine提供的onGamePaused和onGameResumed實(shí)現(xiàn)同等功能(最近把LGame也加上了這樣的兩個(gè)函數(shù),并且禁止了LGameAndroid2DActivity子類重載onResume與onPause,務(wù)求減少用戶錯(cuò)誤重載導(dǎo)致的程序異常)。
1.3 AndEngine的基本運(yùn)行方式:
上文介紹了AndEngine的基本運(yùn)行機(jī)制與運(yùn)行流程,然而僅僅這樣AndEngine還是無(wú)法實(shí)際運(yùn)行,因?yàn)镋ngine與Scene都沒有獲得具體實(shí)現(xiàn)。假如我們想要在屏幕上顯示出當(dāng)前應(yīng)用FPS數(shù),至少需要做如下改動(dòng),才能滿足一個(gè)最為基本的AndEngine應(yīng)用:
運(yùn)行效果如下圖所示:
另外,事實(shí)上BaseGameActivity并非AndEngine提供的唯一Activity,其UI包下尚有以SplashScene場(chǎng)景作為特效啟動(dòng)的BaseSplashActivity類,以及通過重載getLayoutID與getRenderSurfaceViewID這兩個(gè)抽象函數(shù),調(diào)用指定布局與視圖的LayoutGameActivity類。不過除了上述特點(diǎn),它們與BaseGameActivity就再無(wú)區(qū)別了。
二、如何使用AndEngine中的常用功能:
事實(shí)上,AndEngine中組件顆粒都非常細(xì)小,幾乎每個(gè)由AndEngine提供的功能都會(huì)有一個(gè)對(duì)應(yīng)的類存在;個(gè)人認(rèn)為,AndEngine將許多很小很小的功能,做成了太多太多的模塊,似乎有些封裝過度。
比如僅Engine就衍生出DoubleSceneSplitScreenEngine(可以同時(shí)顯示并緩存兩個(gè)Scene的Engine,通過setFirstScene以及setSecondScene進(jìn)行雙屏切換,即分屏用Engine)、SingleSceneSplitScreenEngine(與DoubleSceneSplitScreenEngine類似,但一次只能顯示一個(gè)畫面)、LimitedFPSEngine(可限制FPS速度的Engine,重載了標(biāo)準(zhǔn)Engine的onUpdate函數(shù),減速方式為常見的線程延遲)、FixedStepEngine(與LimitedFPSEngine近似,重載了標(biāo)準(zhǔn)Engine的onUpdate函數(shù),但是它通過反復(fù)while方式最大限度矯正AndEngine內(nèi)部計(jì)時(shí)器的累加數(shù)值,以求每次線程主循環(huán)的幀數(shù)都與預(yù)想幀數(shù)相等)等許多子類(目前細(xì)分還在不斷增加)。
其實(shí),這些功能完全可以進(jìn)行統(tǒng)一實(shí)現(xiàn),而不必占據(jù)那么的應(yīng)用空間與用戶記憶細(xì)胞(PS:有日本人(疑似,服務(wù)器在東京)做過一個(gè)叫e3roid的同類項(xiàng)目,雖然結(jié)構(gòu)異常近似AndEngine,個(gè)人認(rèn)為具體實(shí)現(xiàn)卻比AndEngine更合理,項(xiàng)目在:http://www.e3roid.com,有時(shí)間小弟會(huì)單獨(dú)介紹一下)。
當(dāng)然,這篇文章是對(duì)AndEngine的使用入門,而并非對(duì)AndEngine的“抱怨入門”,所以下面開始,小弟將對(duì)AndEngine的主要功能進(jìn)行初步講解。
2.1 AndEngine的IUpdateHandler接口:
IUpdateHandler類是AndEngine引擎中使用頻率非常之高的組件之一,其本身是一個(gè)接口,內(nèi)部有onUpdate以及reset兩個(gè)函數(shù)等待實(shí)現(xiàn),幾乎所有AndEngine應(yīng)用中都必然會(huì)看到它的身影,它也是AndEngine添加具體業(yè)務(wù)到游戲業(yè)務(wù)線程中的主要方法之一。
具體的講,所有通過AndEngine中registerUpdateHandler函數(shù)注冊(cè)的IUpdateHandler,都會(huì)被保存到一個(gè)叫做UpdateHandlerList的IUpdateHandler接口集合當(dāng)中。雖然UpdateHandlerList本身也是一個(gè)IUpdateHandler接口的實(shí)現(xiàn),然而它的地位卻比較特殊,基本只存在于Engine及Scene類中,并只供Engine類中的onTickUpdate函數(shù)調(diào)用(PS:Scene類中雖有獨(dú)立的UpdateHandlerList,但事實(shí)上它依舊只被Engine中的onTickUpdate執(zhí)行)。每當(dāng)AndEngine業(yè)務(wù)線程循環(huán)onTickUpdate這個(gè)Engine內(nèi)部方法時(shí),都會(huì)調(diào)用UpdateHandlerList中存在的所有IUpdateHandler,直到注銷相關(guān)的IUpdateHandler實(shí)例為止。
另外,與UpdateHandlerList集合類作用類似的還有RunnableHandler類,該類同樣是IUpdateHandler的具體實(shí)現(xiàn),它的作用在于保存并執(zhí)行一次標(biāo)準(zhǔn)Runnable(每次業(yè)務(wù)循環(huán)后都會(huì)清空RunnableHandler的內(nèi)部數(shù)據(jù))。該類在AndEngine業(yè)務(wù)線程中的執(zhí)行時(shí)機(jī)略早于UpdateHandlerList,我們可以通過RunnableHandler類中的postRunnable函數(shù),或Engine類中的runOnUpdateThread函數(shù)添加Runnable到該集合(runOnUpdateThread函數(shù)為postRunnable函數(shù)的調(diào)用封裝,Engine類及相關(guān)子類,BaseGameActivity類及相關(guān)子類中可見)。
2.2 AndEngine的Async方法:
默認(rèn)情況下,AndEngine的資源加載會(huì)在構(gòu)建Engine之后,調(diào)用onLoadResources函數(shù)時(shí)進(jìn)行同步加載。但如果一次性加載資源太多時(shí),便可能會(huì)面臨一個(gè)問題,那就是Android系統(tǒng)將自動(dòng)關(guān)閉長(zhǎng)期無(wú)響應(yīng)的UI。所以一旦采取同步執(zhí)行的加載策略,數(shù)據(jù)量過大時(shí)就有可能將我們的APK卡死。因此,這就需要異步加載策略來(lái)解決問題,而AndEngine也確實(shí)提供了我們這樣的異步加載方式。
具體的講,AndEngine對(duì)Android系統(tǒng)自帶的AsyncTask類進(jìn)行了適當(dāng)封裝(具體封裝在BaseActivity類中,該類為BaseGameActivity的父類,AndEngine由此類開始實(shí)際繼承Activity,但BaseGameActivity的主要功能并不在此類),只要通過doAsync或者doProgressAsync函數(shù)就可以調(diào)用,實(shí)現(xiàn)代碼如下所示:
效果圖如下所示:
2.3 AndEngine中的精靈調(diào)用:
精靈類,是一個(gè)大家耳熟能詳,并且任何游戲引擎無(wú)法回避的關(guān)鍵性組件之一,它常常被用來(lái)表示一個(gè)游戲中角色或者特定畫面要素。如此重要的存在,AndEngine當(dāng)然也不能缺少,其精靈類的基本使用方法如下所示:
2.3 AndEngine的精靈動(dòng)畫:
在絕大多數(shù)的游戲開發(fā)中,僅僅有精靈類存在是并不足夠的,我們往往還需要讓精靈作出絢麗的效果以吸引用戶眼球,而這些效果在AndEngine中,統(tǒng)一通過它所提供的各個(gè)Modifier類進(jìn)行實(shí)現(xiàn)。具體調(diào)用代碼如下所示:
效果如下圖所示:
三、AndEngine的常用模塊介紹:
由于AndEngine包的下屬類較多,并且細(xì)分也較為龐雜,在一篇文章中一次性介紹完畢幾乎不可能實(shí)現(xiàn)。所以下面開始,小弟會(huì)就AndEngine的一些核心模塊進(jìn)行簡(jiǎn)明扼要的說(shuō)明,但如果前文做過說(shuō)明的下文會(huì)一筆帶過。
PS:事實(shí)上,就連AndEngine作者也不可能做到詳細(xì)介紹,畢竟到目前為止AndEngine壓根沒有出過文檔。(連andengineexamples下的示例代碼都已經(jīng)和最新的AndEngine源碼脫離了……)
1、關(guān)于Engine:
Engine是AndEngine的核心所在,它對(duì)AndEngine引擎中Camera、Scene等重要組件進(jìn)行了統(tǒng)一管理,但必須和BaseGameActivity合作使用,利用EngineOptions類可以對(duì)其進(jìn)行必要的參數(shù)配置。
2、關(guān)于BaseGameActivity:
如果您想正常使用AndEngine,那么當(dāng)前Activity就必須繼承自BaseGameActivity或其子類,否則你連初始化Engine也做不到。雖然它還有父類BaseActivity,但BaseActivity只提供了一些異步加載方法而無(wú)關(guān)AndEngine的主體實(shí)現(xiàn)。因此,BaseGameActivity就是實(shí)際上的AndEngine最基礎(chǔ)用類無(wú)疑。
3、關(guān)于IResolutionPolicy:
IResolutionPolicy是一個(gè)接口類,其中只規(guī)定了onMeasure函數(shù)的實(shí)現(xiàn)格式。事實(shí)上,AndEngine中所有該類具體實(shí)現(xiàn)的作用與標(biāo)準(zhǔn)View中的onMeasure函數(shù)幾乎一致,也會(huì)被標(biāo)準(zhǔn)View中的onMeasure函數(shù)重載調(diào)用(具體調(diào)用在AndEngine的RenderSurfaceView類當(dāng)中)。而且除BaseResolutionPolicy外,所有AndEngine的IResolutionPolicy實(shí)現(xiàn)也都調(diào)用了View的setMeasuredDimensionProxy函數(shù)。
在AndEngine的org.anddev.andengine.engine.options.resolutionpolicy包下有一組IResolutionPolicy接口的具體實(shí)現(xiàn),分別為BaseResolutionPolicy(除了會(huì)校驗(yàn)一下屏幕大小外,什么也不做)、FillResolutionPolicy(拉伸游戲畫面為全屏填充,視攝像機(jī)大小不同,會(huì)有不同程度變形)、FixedResolutionPolicy(強(qiáng)行規(guī)定游戲畫面為固定大小,此設(shè)置不會(huì)自動(dòng)適應(yīng)屏幕大小),RatioResolutionPolicy(按比例修正畫面大小,以適應(yīng)屏幕大小),RelativeResolutionPolicy(根據(jù)構(gòu)建RelativeResolutionPolicy時(shí)的縮放參數(shù),縮放游戲屏幕為指定比例)。
最后,所有IResolutionPolicy的實(shí)現(xiàn)類,都要隨著EngineOptions于初試化時(shí)傳遞給Engine實(shí)例才起作用。
4、關(guān)于Camera:
該類即我們常說(shuō)的游戲攝像機(jī),在AndEngine的Camera有兩種作用,一是用以調(diào)節(jié)屏幕的顯示區(qū)域,二是利用HUD類實(shí)際繪制游戲屏幕于手機(jī)之上。
5、關(guān)于Scene:
場(chǎng)景容器,作用類似于LGame中的Screen,能夠?qū)⒛骋惶囟▓?chǎng)景作為游戲模塊進(jìn)行調(diào)用,我們可以利用它來(lái)切換當(dāng)前游戲的畫面與觸摸屏監(jiān)聽,切換方法是利用Engine.setScene。
6、關(guān)于Entity:
Entity是IEntity接口的具體實(shí)現(xiàn),也是AndEngine中無(wú)論Scene、Layer、Sprite(這個(gè)繼承關(guān)系比較遠(yuǎn),中間隔了BaseRectangle、RectangularShape、GLShape、Shape等上級(jí)類,不過追溯源頭始終繼承自Entity)的統(tǒng)一父類,通過Entity我們可以讓AndEngine中場(chǎng)景,或場(chǎng)景中某精靈實(shí)現(xiàn)統(tǒng)一效果的縮放、旋轉(zhuǎn)、變色等操作。
7、關(guān)于Texture:
Texture是AndEngine所提供的紋理用類,但Texture本身(在AndEngine中)并沒有提供加載圖片的方法,必須通過TextureRegionFactory類(更準(zhǔn)確的說(shuō),依賴它內(nèi)部封裝的TextureRegion、BuildableTexture等類)與之合作才可以加載紋理。除此之外,AndEngine要求所加載紋理(圖片)大小必須為2的整數(shù)次冪。
8、關(guān)于TextureRegion:
TextureRegion的父類是抽象類BaseTextureRegion,主要功能也被封裝在BaseTextureRegion類當(dāng)中,AndEngine提供了TextureRegionFactory這個(gè)工廠類用以簡(jiǎn)化構(gòu)建TextureRegion的流程。單就TextureRegion來(lái)講,它的作用似乎就是讓系統(tǒng)知道如何剪切一個(gè)紋理,并返回一個(gè)這樣的紋理給你。
然而,事實(shí)上AndEngine中只有TextureRegion才更接近于通常意義上的Texture。或者說(shuō),只有TextureRegion + Texture時(shí),我們才能較為完整的使用AndEngine紋理功能。嚴(yán)肅的講,AndEngine中的Texture有很多功能必須靠TextureRegion最終完成,比如AndEngine中的Sprite必須加載TextureRegion才能使用Texture,而不是直接調(diào)用Texture,TMXTiledMap中讀取指定瓦片返回的也是TextureRegion,而非直接的Texture(進(jìn)行畫面渲染時(shí)AndEngine內(nèi)部會(huì)調(diào)用TextureRegion中的Texture引用,但也只允許如此調(diào)用);應(yīng)該說(shuō),AndEngine中見Texture幾乎必見TextureRegion,二者無(wú)法分離,缺一不可。
9、關(guān)于TextureOptions
在AndEngine中,TextureRegionFactory類決定紋理的加載路徑,Texture類作為承載紋理的實(shí)體對(duì)象,而TextureOptions類決定了紋理的渲染方式。
也即是說(shuō),OpenGLES將以何種方式顯示紋理圖像,都由TextureOptions類所決定。在當(dāng)前最新版本的AndEngine中,默認(rèn)提供了:
1、NEAREST(Nearest濾波,實(shí)現(xiàn)上依賴GL_NEAREST做不光滑過濾,紋理環(huán)繞模式為GL_CLAMP_TO_EDGE,顯示速度快畫質(zhì)差)
2、BILINEAR(雙線性插值,實(shí)現(xiàn)上依賴GL_LINEAR做線性濾波,紋理環(huán)繞模式為GL_CLAMP_TO_EDGE,顯示速度慢畫質(zhì)佳)
3、REPEATING(與NEAREST同為Nearest濾波,但紋理環(huán)繞模式為GL_REPEAT,會(huì)自動(dòng)填充紋理上的空白區(qū)域,顯示速度較快畫質(zhì)差)
4、REPEATING_BILINEAR(與BILINEAR同為雙線性插值,但紋理環(huán)繞模式為GL_REPEAT,會(huì)自動(dòng)填充紋理上的空白區(qū)域,顯示速度很慢畫質(zhì)佳(低端機(jī)跑此模式異常悲劇,高端機(jī)尚可))
5、NEAREST_PREMULTIPLYALPHA(所有[PREMULTIPLYALPHA]結(jié)尾的TextureOptions與其它同名類差別僅在于是否支持根據(jù)Alpha值設(shè)置透明紋理,以下同)
6、BILINEAR_PREMULTIPLYALPHA
7、REPEATING_PREMULTIPLYALPHA
8、REPEATING_BILINEAR_PREMULTIPLYALPHA等靜態(tài)對(duì)象。
以上TextureOptions實(shí)例都可以通過“TextureOptions.XXXXXX”的方式進(jìn)行引用并設(shè)置給Texture。事實(shí)上,除了AndEngine提供的Texture渲染模式,我們也可以按照規(guī)則自行構(gòu)建需要的TextureOptions。
比如構(gòu)建一個(gè)混插的TextureOptions:
new TextureOptions(GL10.GL_LINEAR_MIPMAP_LINEAR, GL10.GL_LINEAR_MIPMAP_NEAREST, GL10.GL_REPEAT, GL10.GL_REPEAT, GL10.GL_MODULATE, true);
另外,TextureOptions默認(rèn)還有DEFAULT模式,不過該模式實(shí)際引用為NEAREST_PREMULTIPLYALPHA,也就是紋理低畫質(zhì)但支持Alpha。如果您想要兼容低端機(jī),則建議不要使用含有【BILINEAR】字樣的AndEngine加載大圖,而應(yīng)直接使用TextureOptions.DEFAULT或TextureOptions.NEAREST_PREMULTIPLYALPHA;因?yàn)锽ILINEAR模式對(duì)硬件要求較高,如果以此模式將較大紋理放到低端機(jī)上渲染,速度很可能無(wú)法保證。但是,假如您的游戲只針對(duì)高端機(jī)用戶便無(wú)需介懷了。
————————————————————————————————————————
最近準(zhǔn)備先把常見Android游戲引擎的粗略使用入門寫全,如果大家對(duì)某幾個(gè)引擎表現(xiàn)的興趣較為濃厚,小弟也會(huì)進(jìn)一步詳細(xì)講解。
另外小弟前天剛回北京,所以把LGame的開發(fā)又耽誤了一段,沒能如預(yù)想中在本周發(fā)布0.3,但也快到收尾,在性能上也強(qiáng)化了不少。另外近期www.java4k.com網(wǎng)站更新了不少有價(jià)值的Java小游戲Demo。(小弟不是教大家偷奸耍滑,但反向一下源碼,就可以按照常規(guī)的Java2D方式把其業(yè)務(wù)實(shí)現(xiàn)挪到LGame中了嘛,純學(xué)習(xí)用……)
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

