Libgdx作者博客:http://www.badlogicgames.com/
Libgdx項目地址:http://code.google.com/p/libgdx/
Libgdx是一款支持2D與3D游戲開發的游戲類庫,兼容大多數微機平臺(標準JavaSE實現,能運行在Mac、Linux、Windows等系統)與Android平臺(Android1.5以上即可使用,Android2.1以上可滿功率發揮),
Libgdx由audio、files、graphics、math、physics、scenes、utils這些主要類庫所組成,它們分別對應了Libgdx中的音頻操作,文件讀取,2D/3D渲染,Libgdx繪圖相關運算,Box2D封裝,2D/3D游戲組件(3D部分目前無組件),以及Libgdx內置工具類。
Libgdx主要構成如下所示(Libgdx作者wiki提供):
下面開始,我將就Libgdx的具體實現,開始講解如何正確使用Libgdx類庫。
不過在正式開始之前,我們首先還得講講Gdx類。
關于Libgdx中的Gdx類:
單從表面上看,Gdx類占用空間不足2KB,甚至不具備一行可以被直接執行的函數,并沒什么重要好說。
然而,真實的Gdx卻是Libgdx類庫運行的核心所在,沒有它你將寸步難行,不單運行Graphics、Input、Files、Audio、AndroidApplication等Libgdx關鍵部分所必需的實例會在Libgdx初始化時注入Gdx中對應的graphics、input、files、audio、app等靜態變量里面,就連Libgdx對OpenGL接口(或OpenGLES,視Libgdx運行平臺而定,以下統稱OpenGL)的GL10、GL11、GL20、GLCommon等封裝類也會在Graphics實例化時分別注入到gl10、gl11、gl20、gl這四個同樣位于Gdx的靜態變量當中(在Graphics中也會繼續保留它們的引用,因此無論你執行Gdx.graphics.getGL10還是Gdx.gl10,其實都在調用同一個靜態變量)。事實上,如果你想不使用Gdx而正常運行Libgdx,那么除了重構源碼,就再沒有任何辦法可想了。
PS:如果你不清楚自己究竟在什么環境使用Libgdx,其實也不必強分gl10或gl11,大可以通過Gdx.gl方式調用Libgdx中對于OpenGL接口的默認封裝(執行某些非多版本共有接口時,依舊需要使用對應版本專屬gl)。
想要使用Libgdx,卻不明白Gdx是干什么用的,那么一切就都是空談。
下面開始,我將具體講解Libgdx中的圖像處理與游戲組件部分:
關于Libgdx的圖像處理部分:
Mesh:
本質上講,Libgdx中所有可見的3D物體首先都是一個Mesh(網格,或者說三維網格形式的高級圖元)。Mesh是如何生成的呢?眾所周知,數學上講的立體幾何由點、線、面三部分組成,無論多么復雜的圖像也可以分解為無數細小的這三部分,或者說可以由非常基礎的N個這三部分所組合而成;到了3D游戲開發時,當我們要構建復雜的3D圖像,首先會以一系列有序的vertices(頂點)構成這些具體的點、線、三角要素,即構成繪圖基本圖元(Primitives),再將基本圖元組合成更完整的高級圖元也就是具體3D對象。因此,如果對Mesh概念進行簡單的理解,其實它就是一個象征完整圖像的基本圖元集合體,Libgdx先讓我們把一個個細分的vertices組成基本圖元,再由Mesh類將基本圖元制成更加復雜的高級圖元展示出來。
具體可見Libgdx作者提供的returntomarchfeld示例,基本效果如下圖所示:
(勿看FPS,一切信真機)
PS:如果對此類認識不足,可以去玩玩模擬人生,下個修改器嘗試編輯角色或物品造型后就懂了……
Texture:
Libgdx所提供的游戲紋理用類,其實質可理解為保存在顯存中的Image,它以貼圖的方式通過OpenGL將圖片顯示到游戲界面之上。Libgdx的紋理可以直接從指定文件路徑加載,也可以通過它提供的Pixmap類憑空創建(它的Texture(int width, int height, Format format)構造內部直接調用了Pixmap,不是必須在外部生成Pixmap后注入)。另外在加載Texture時,個人建議通過Libgdx提供的TextureDict.loadTexture函數調用,該方法內部提供了Texture緩存管理,能夠避免無意義的資源重復加載。此外,Texture通常會與TextureRegion類配套使用,利用TextureRegion包裝Texture后,再利用SpriteBatch進行繪制,可以很方便的修訂Texture為我們需要的顯示范圍。還有,Libgdx中Sprite類為TextureRegion子類,因此能夠將Sprite當作TextureRegion來使用,只是Sprite類比TextureRegion有所擴展。不過Libgdx的SpriteCache類并沒有繼承Sprite或TextureRegion,所以起不到TextureRegion的作用,只能構建一組靜態貼圖集合罷了,特此說明。
Pixmap:
Libgdx所提供的像素級圖像渲染用類,由于Libgdx目前以JNI方式自帶圖像解碼器,所以我們可以直接將Pixmap理解為一個Android中Bitmap的替代者,兩者間實現細節雖有差別,但具體作用卻大同小異。Pixmap支持Alpha、LuminanceAlpha、RGB565、RGBA4444、RGB888、RGBA8888等五種圖像彩色模式,支持png、jpg、bmp等三種圖像文件的讀取和加載。一般來說,Pixmap必須和Texture混用才能真正顯示畫面。不過在事實上,Libgdx的Texture里已經內置有Pixmap了。
BitmapFont:
Libgdx所提供的OpenGL文字用類,構造BitmapFont時需要一個描述文字構成的fnt文件,和一個提供文字圖片的png文件(PS:在Libgdx的com.badlogic.gdx.utils包下有提供內置字庫,目前僅支持英文、數字和常見符號),同SpriteBatch相配合時能夠完成一些基礎的文字繪圖。值得一提的是,我們也可以使用BitmapFontCache類將BitmapFont包裝成了一個靜態的Font實例,以避免大量貼圖時產生的不必要損耗。
SpriteBatch:
Libgdx所提供的紋理渲染器,本質上是OpenGL的簡易封裝體,具體實現上與XNA中的SpriteBatch類非常近似,每次調用SpriteBatch類都必須以begin函數開頭,以end函數結尾。由于Libgdx中SpriteBatch提供的功能還非常有限,所以在完全不懂OpenGL的前提下使用其進行游戲開發或許有一定難度。
ShaderProgram:
Libgdx所提供的著色器,在Android環境使用時需要GLES2.0或以上版本才能完整支持的高級渲染功能之一,內部封裝著GLES2.0專用的頂點著色與片斷著色Shader Model,它的本質作用是對3D對象表面進行渲染處理,此物性能基本取決于GPU(除了Google Nexus系列手機暫未見能完全跑出速度的機型)。
FrameBuffer:
Libgdx所提供的幀緩沖器,在Android環境使用時需要GLES2.0或以上版本才能完整支持的高級渲染功能之一,也就是常說的FrameBuffer Object(FBO)功能封裝(用過JavaSE或JavaME開發游戲的朋友,繪圖時大概都接觸過雙緩存這個概念,雖然有所差別,不過將FrameBuffer理解成起近似作用也未嘗不可)此物性能徹底取決于GPU(除了Google Nexus系列手機暫未見能完全跑出速度的機型)。
關于Libgdx的游戲組件部分:
在最近更新的Libgdx中,與游戲顯示相關度最高的包總共有兩個,一個是graphics包,其中包含著Libgdx為進行OpenGL渲染所提供的功能實現,而另一個,就是下面介紹的scenes包,這里包含著Libgdx所提供的可以直接使用到游戲中的游戲組件,共分scenes2d以及scenes3d兩大部分(3D部分暫無內容)。其中2D部分的核心在于Actor類,Libgdx所有2D組件使用都圍繞著Actor展開。
對于Libgdx中游戲組件使用的簡單關系說明:
AndroidApplication
(Activity的子類,只有啟動類繼承了AndroidApplication并執行才能啟動Libgdx類庫)
|
ApplicationListener
(僅可在初始化時注入ApplicationListener,此后除非替換Activity否則無法切換ApplicationListener) - Game
(ApplicationListener的libgdx抽象實現,其中Screen可切換)
|
Screen
(基本函數與ApplicationListener近乎一致,唯一差別在于可以通過Game類用setScreen函數進行切換,如不使用Game類則可無視它的存在)
|
Stage
(游戲場景用類,用以管理添加其中的具體Actor,管理Actor的手段在于內置的Group類)
|
Group
(本身為Actor的具體實現,能夠處理注入其中的Actor,也能以遞歸方式管理注入其中的其它Group)
|
Actor
(游戲用演員或者說角色,與Action類組合使用時可以產生不同種類的“動畫行為”,Action部分的具體實現基本與Cocos2D一致)
|
Image、Button、Label等
(細分Actor的具體實現,以重載方式響應事件,除Group外相互間不能組合疊加,事件能否傳遞取決于上級組件是否設置了相關監聽)
就目前來說,Libgdx可用的游戲組件相對比較稀少,部分功能或者需要用戶自行實現。不過最近有一位網名moritz的手機游戲“半全職”開發者(因為他自己說手機游戲并不是他唯一的收入來源)已經加入Libgdx項目,未來將重點改進Libgdx的scene2d部分,鑒于Libgdx作者為此特意寫了一篇名為“welcome moritz”的博文,moritz此人應該是有一定能力的家伙,對于Lingdx未來表現大約還是值得期待的(話說,莫非moritz只對改造Libgdx的2D模塊有興趣?Libgdx作者博文中提到目前moritz開發的3D游戲沒有使用Libgdx——那啥,先把3D組件部分做出來吧,現在是NULL啊……)。
在Libgdx的SVN,也有一些具體的游戲示例,大家可以下載后親身體驗其效果。
PS:為體現Libgdx最新特性,上述示例使用的Libgdx是2月1日從Libgdx SVN下載的版本(2011年1月28日更新版),請自行下載相關類庫,以保證所用版本維持在最新。
附錄,使用Libgdx時的幾點注意事項:
1、Libgdx使用笛卡爾坐標系(初始坐標為左下0,0),而JavaSE、JavaME以及標準Android系統(還有LGame引擎)使用的是屏幕坐標系(初始坐標為左上0,0),程序員在使用時必須分清差別,以免不知道如何定位(通常笛卡爾系Y軸由下向上延伸,屏幕系Y軸由上向下延伸)。
2、在Android環境使用Libgdx的Gdx.files.internal方法時(即FileHandle類以FileType.Internal模式工作),要讀取的文件必須置于Assets文件夾下才能讀取,在Linux、Mac、Windows環境下則可以置于除jar內部外的任何可讀取位置。
3、Libgdx以native方式自帶圖像解碼器,通過其提供的Pixmap可以對指定圖像進行像素級渲染操作,從而不依賴Android的Bitmap加載處理圖像,不過目前只支持png、jpg、bmp三種圖片格式。
4、Libgdx要求在游戲中使用的圖片寬與高皆為2的整數次冪,否則會產生一個Gdx異常并禁止加載行為(texture width and height must be powers of two)。
5、Libgdx以ApplicationListener作為游戲的基礎界面容器,其作用近似LGame中的Screen,但并不完全一致,因為Libgdx并沒有提供可以直接切換ApplicationListener的函數。目前最新版本的Libgdx中提供了Game類(ApplicationListener子類,本身為抽象類)和一個供Game類調用的Screen類用以解決此問題。具體的Libgdx切換游戲畫面方法是,先用繼承Game類的游戲窗體進行initialize讓基礎畫面顯示,再讓具體的細分游戲模塊繼承Screen類進行不同游戲畫面的具體繪圖,而后Game類通過setScreen方法進行畫面切換。
6、Libgdx的圖像加載處理(以及部分渲染),音頻播放和自帶的Box2D封裝皆通過JNI方式實現,因此必須在libs文件夾下添加armeabi(或高版本Android系統支持的armeabi-v7a)文件夾以及相關so文件Android版Libgdx才能正常運行。
7、千萬不要以模擬器上的Libgdx運行速度判定其性能,否則很容易產生誤判(也不建議用性能不好的真機運行)
————————————————————
如果有人關心這些Android游戲框架的話,小弟會按照某國際友人寫的Android的15款開源框架那篇英文文章里介紹過的框架一一寫出基礎使用入門(這里吐句槽,洋人怎么也玩山寨啊,而且是先翻譯再山寨~~~),沒人關心就算了……
浙公網安備 33010602011771號