Android遊戲框架Libgdx使用入門

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提供):

 

00

 

下面開始,我將就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示例,基本效果如下圖所示:

 

00

 

(勿看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的作用,只能構建一組靜態貼圖集合罷了,特此說明。

[java] view plaincopy
  1. // Libgdx的Texture與Sprite使用  
  2. public class Main extends AndroidApplication {  
  3.     class TestSprite implements ApplicationListener {  
  4.         // 準備繪圖用SpriteBatch  
  5.         SpriteBatch spriteBatch;  
  6.         // 準備遊戲精靈  
  7.         Sprite sprite;  
  8.         // 準備圖片加載用Texture  
  9.         Texture texture;  
  10.         public void create() {  
  11.             // 構建SpriteBatch  
  12.             spriteBatch = new SpriteBatch();  
  13.             // 構建Texture,圖像寬與高大小都必須爲2的整數次冪,否則提示異常  
  14.             // PS:在Android環境使用Libgdx的internal加載時必須文件必須位於assets目錄下  
  15.             texture = new Texture(Gdx.files.internal("mySprite.png"));  
  16.             // 以指定Texture構建Sprite  
  17.             sprite = new Sprite(texture);  
  18.             // 定位到100, 180(Libgdx使用標準笛卡爾座標系,自左下0,0開始)  
  19.             sprite.setPosition(100180);  
  20.         }  
  21.         public void render() {  
  22.             // 清屏  
  23.             Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);  
  24.             // 初始化繪圖調用  
  25.             spriteBatch.begin();  
  26.             // 繪製精靈到遊戲屏幕  
  27.             sprite.draw(spriteBatch);  
  28.             // 結束繪圖調用  
  29.             spriteBatch.end();  
  30.         }  
  31.         public void dispose() {  
  32.             // 釋放佔用的資源  
  33.             spriteBatch.dispose();  
  34.             texture.dispose();  
  35.         }  
  36.         public void resume() {  
  37.         }  
  38.         public void pause() {  
  39.         }  
  40.         public void resize(int width, int height) {  
  41.         }  
  42.     }  
  43.     public void onCreate(Bundle bundle) {  
  44.         super.onCreate(bundle);  
  45.         // 初始化遊戲屏幕,並設置是否支持GLES 2.0,如果您對向下兼容沒什麼需要選擇true即可(2.1以上),否則選擇false。  
  46.         initialize(new TestSprite(), true);  
  47.     }  
  48. }  


Pixmap:
 

Libgdx所提供的像素級圖像渲染用類,由於Libgdx目前以JNI方式自帶圖像解碼器,所以我們可以直接將Pixmap理解爲一個Android中Bitmap的替代者,兩者間實現細節雖有差別,但具體作用卻大同小異。Pixmap支持Alpha、LuminanceAlpha、RGB565、RGBA4444、RGB888、RGBA8888等五種圖像彩色模式,支持png、jpg、bmp等三種圖像文件的讀取和加載。一般來說,Pixmap必須和Texture混用才能真正顯示畫面。不過在事實上,Libgdx的Texture裏已經內置有Pixmap了。

 

[java] view plaincopy
  1. // Libgdx的Pixmap使用  
  2. public class Main extends AndroidApplication {  
  3.       
  4.     class TestPixmap implements ApplicationListener {  
  5.         // 準備繪圖用SpriteBatch  
  6.         SpriteBatch spriteBatch;  
  7.         // Pixmap是Libgdx提供的針對opengl像素操作的上級封裝,它可以憑空構建一個像素貼圖,  
  8.         // 但是它的現實必須通過Texture。  
  9.         Pixmap pixmap;  
  10.         // 準備Texture  
  11.         Texture texture;  
  12.         public void create() {  
  13.             // 構建SpriteBatch  
  14.             spriteBatch = new SpriteBatch();  
  15.             // 構建Pixmap(在Android環境使用internal加載模式時,文件必須放置於assets文件夾下)  
  16.             pixmap = new Pixmap(Gdx.files.internal("myPixmap.png"));  
  17.             // 繪製一個藍方塊到Ball圖像之上  
  18.             pixmap.setColor(Color.BLUE.r, Color.BLUE.g, Color.BLUE.b,  
  19.                     Color.BLUE.a);  
  20.             pixmap.drawRectangle(15154040);  
  21.             // 以指定Pixmap構建Texture  
  22.             texture = new Texture(pixmap);  
  23.             // 注入Texture後的pixmap已經沒用,可以註銷  
  24.             pixmap.dispose();  
  25.         }  
  26.         public void dispose() {  
  27.             spriteBatch.dispose();  
  28.             texture.dispose();  
  29.         }  
  30.         public void pause() {  
  31.         }  
  32.         public void render() {  
  33.             // 清屏  
  34.             Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);  
  35.             // 初始化繪圖調用  
  36.             spriteBatch.begin();  
  37.             // 繪製精靈到遊戲屏幕  
  38.             spriteBatch.draw(texture, 100180);  
  39.             // 結束繪圖調用  
  40.             spriteBatch.end();  
  41.         }  
  42.         public void resize(int width, int height) {  
  43.         }  
  44.         public void resume() {  
  45.         }  
  46.     }  
  47.     public void onCreate(Bundle bundle) {  
  48.         super.onCreate(bundle);  
  49.         // 初始化遊戲屏幕,並設置是否支持GLES 2.0,如果您對向下兼容沒什麼需要選擇true即可(2.1以上),否則選擇false。  
  50.         initialize(new TestPixmap(), true);  
  51.     }  
  52. }  



BitmapFont:
 

Libgdx所提供的OpenGL文字用類,構造BitmapFont時需要一個描述文字構成的fnt文件,和一個提供文字圖片的png文件(PS:在Libgdx的com.badlogic.gdx.utils包下有提供內置字庫,目前僅支持英文、數字和常見符號),同SpriteBatch相配合時能夠完成一些基礎的文字繪圖。值得一提的是,我們也可以使用BitmapFontCache類將BitmapFont包裝成了一個靜態的Font實例,以避免大量貼圖時產生的不必要損耗。

 

[java] view plaincopy
  1. //libgdx的文字顯示  
  2. public class Main extends AndroidApplication {  
  3.     class TestFont extends Game {  
  4.         // SpriteBatch是libgdx提供的opengl封裝,可以在其中執行一些常規的圖像渲染,  
  5.         // 並且libgdx所提供的大多數圖形功能也是圍繞它建立的。  
  6.         SpriteBatch spriteBatch;  
  7.         // BitmapFont是libgdx提供的文字顯示用類,內部將圖片轉化爲可供opengl調用的  
  8.         // 文字貼圖(默認不支持中文)。  
  9.         BitmapFont font;  
  10.         public void create() {  
  11.             //構建SpriteBatch用於圖像處理(內部調用opengl或opengles)  
  12.             spriteBatch = new SpriteBatch();  
  13.             //構建BitmapFont,必須有一個fnt文件描述文字構成,一個圖片文件提供文字用圖  
  14.             font = new BitmapFont(Gdx.files.internal("font.fnt"), Gdx.files  
  15.                     .internal("font.png"), false);  
  16.         }  
  17.         public void render() {  
  18.                 // 調用清屏  
  19.             Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);  
  20.             // 初始要有begin起始  
  21.             spriteBatch.begin();  
  22.             // 顯示文字到屏幕指定位置  
  23.             // PS:Libgdx採用標準笛卡爾座標系,自左下0,0開始  
  24.             font.draw(spriteBatch, "FPS" + Gdx.graphics.getFramesPerSecond(),  
  25.                     5475);  
  26.             font.draw(spriteBatch, "Hello Libgdx"255255);  
  27.             // 結束要有end結尾  
  28.             spriteBatch.end();  
  29.         }  
  30.         public void resize(int width, int height) {  
  31.         }  
  32.         public void pause() {  
  33.         }  
  34.         public void resume() {  
  35.         }  
  36.         public void dispose() {  
  37.             // 釋放佔用的資源  
  38.             spriteBatch.dispose();  
  39.             font.dispose();  
  40.         }  
  41.     }  
  42.     public void onCreate(Bundle bundle) {  
  43.         super.onCreate(bundle);  
  44.         // 初始化遊戲屏幕,並設置是否支持GLES 2.0,如果您對向下兼容沒什麼需要選擇true即可(2.1以上),否則選擇false。  
  45.         initialize(new TestFont(), true);  
  46.     }  
  47. }  

 

00


SpriteBatch:
 

Libgdx所提供的紋理渲染器,本質上是OpenGL的簡易封裝體,具體實現上與XNA中的SpriteBatch類非常近似,每次調用SpriteBatch類都必須以begin函數開頭,以end函數結尾。由於Libgdx中SpriteBatch提供的功能還非常有限,所以在完全不懂OpenGL的前提下使用其進行遊戲開發或許有一定難度。

ShaderProgram:
 

Libgdx所提供的着色器,在Android環境使用時需要GLES2.0或以上版本才能完整支持的高級渲染功能之一,內部封裝着GLES2.0專用的頂點着色與片斷着色Shader Model,它的本質作用是對3D對象表面進行渲染處理,此物性能基本取決於GPU(除了Google Nexus系列手機暫未見能完全跑出速度的機型)。

 

[java] view plaincopy
  1. //libgdx的ShaderProgram使用  
  2. public class Main extends AndroidApplication {  
  3.     class TestShader implements ApplicationListener {  
  4.         ShaderProgram shader;  
  5.         Texture texture;  
  6.         Texture texture2;  
  7.         Mesh mesh;  
  8.         public void create() {  
  9.             // 以下命令供GPU使用(不支持GLES2.0就不用跑了)  
  10.             String vertexShader = "attribute vec4 a_position;   /n"  
  11.                     + "attribute vec2 a_texCoord;   /n"  
  12.                     + "varying vec2 v_texCoord;     /n"  
  13.                     + "void main()                  /n"  
  14.                     + "{                            /n"  
  15.                     + "   gl_Position = a_position; /n"  
  16.                     + "   v_texCoord = a_texCoord;  /n"  
  17.                     + "}                            /n";  
  18.             String fragmentShader = "#ifdef GL_ES/n"  
  19.                     + "precision mediump float;/n"  
  20.                     + "#endif/n"  
  21.                     + "varying vec2 v_texCoord;                            /n"  
  22.                     + "uniform sampler2D s_texture;                        /n"  
  23.                     + "uniform sampler2D s_texture2;                        /n"  
  24.                     + "void main()                                         /n"  
  25.                     + "{                                                   /n"  
  26.                     + "  gl_FragColor = texture2D( s_texture, v_texCoord ) * texture2D( s_texture2, v_texCoord);/n"  
  27.                     + "}                                                   /n";  
  28.             // 構建ShaderProgram  
  29.             shader = new ShaderProgram(vertexShader, fragmentShader);  
  30.             // 構建網格對象  
  31.             mesh = new Mesh(true46new VertexAttribute(Usage.Position, 2,  
  32.                     "a_position"), new VertexAttribute(  
  33.                     Usage.TextureCoordinates, 2"a_texCoord"));  
  34.             float[] vertices = { -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.0f,  
  35.                     1.0f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, 0.0f };  
  36.             short[] indices = { 012023 };  
  37.             // 注入定點座標  
  38.             mesh.setVertices(vertices);  
  39.             mesh.setIndices(indices);  
  40.             // 以Pixmap生成兩個指定內容的Texture  
  41.             Pixmap pixmap = new Pixmap(256256, Format.RGBA8888);  
  42.             pixmap.setColor(1111);  
  43.             pixmap.fill();  
  44.             pixmap.setColor(0001);  
  45.             pixmap.drawLine(00256256);  
  46.             pixmap.drawLine(25600256);  
  47.             texture = new Texture(pixmap);  
  48.             pixmap.dispose();  
  49.             pixmap = new Pixmap(256256, Format.RGBA8888);  
  50.             pixmap.setColor(1111);  
  51.             pixmap.fill();  
  52.             pixmap.setColor(0001);  
  53.             pixmap.drawLine(1280128256);  
  54.             texture2 = new Texture(pixmap);  
  55.             pixmap.dispose();  
  56.         }  
  57.         public void dispose() {  
  58.         }  
  59.         public void pause() {  
  60.         }  
  61.         public void render() {  
  62.             // PS:由於使用了ShaderProgram,因此必須配合gl20模式(否則缺少關鍵opengles接口)  
  63.             Gdx.gl20.glViewport(00, Gdx.graphics.getWidth(), Gdx.graphics  
  64.                     .getHeight());  
  65.             Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);  
  66.             Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0);  
  67.             texture.bind();  
  68.             Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE1);  
  69.             texture2.bind();  
  70.             // 開始使用ShaderProgram渲染  
  71.             shader.begin();  
  72.             shader.setUniformi("s_texture"0);  
  73.             shader.setUniformi("s_texture2"1);  
  74.             mesh.render(shader, GL20.GL_TRIANGLES);  
  75.             // 結束ShaderProgram渲染  
  76.             shader.end();  
  77.         }  
  78.         public void resize(int width, int height) {  
  79.         }  
  80.         public void resume() {  
  81.         }  
  82.     }  
  83.     public void onCreate(Bundle bundle) {  
  84.         super.onCreate(bundle);  
  85.         // 初始化遊戲屏幕,並設置是否支持GLES 2.0,如果您對向下兼容沒什麼需要選擇true即可(2.1以上),否則選擇false。  
  86.         initialize(new TestShader(), true);  
  87.     }  
  88. }  

 


FrameBuffer:

Libgdx所提供的幀緩衝器,在Android環境使用時需要GLES2.0或以上版本才能完整支持的高級渲染功能之一,也就是常說的FrameBuffer Object(FBO)功能封裝(用過JavaSE或JavaME開發遊戲的朋友,繪圖時大概都接觸過雙緩存這個概念,雖然有所差別,不過將FrameBuffer理解成起近似作用也未嘗不可)此物性能徹底取決於GPU(除了Google Nexus系列手機暫未見能完全跑出速度的機型)。

 

[java] view plaincopy
  1. //libgdx的FrameBuffer使用  
  2. public class Main extends AndroidApplication {  
  3.     class TestFrameBuffer implements ApplicationListener {  
  4.         FrameBuffer frameBuffer;  
  5.         Mesh mesh;  
  6.         ShaderProgram meshShader;  
  7.         Texture texture;  
  8.         SpriteBatch spriteBatch;  
  9.         // PS:如果不支持GLES2.0就不用試了  
  10.         public void create() {  
  11.             mesh = new Mesh(true30new VertexAttribute(Usage.Position, 3,  
  12.                     "a_Position"), new VertexAttribute(Usage.ColorPacked, 4,  
  13.                     "a_Color"), new VertexAttribute(Usage.TextureCoordinates,  
  14.                     2"a_texCoords"));  
  15.             float c1 = Color.toFloatBits(25500255);  
  16.             float c2 = Color.toFloatBits(25500255);  
  17.             float c3 = Color.toFloatBits(00255255);  
  18.             mesh.setVertices(new float[] { -0.5f, -0.5f, 0, c1, 000.5f,  
  19.                     -0.5f, 0, c2, 1000.5f, 0, c3, 0.5f, 1 });  
  20.             texture = new Texture(Gdx.files.internal("myTest.png"));  
  21.             spriteBatch = new SpriteBatch();  
  22.             frameBuffer = new FrameBuffer(Format.RGB565, 128128true);  
  23.             String vertexShader = "attribute vec4 a_Position;    /n"  
  24.                     + "attribute vec4 a_Color;/n"  
  25.                     + "attribute vec2 a_texCoords;/n" + "varying vec4 v_Color;"  
  26.                     + "varying vec2 v_texCoords; /n" +  
  27.                     "void main()                  /n"  
  28.                     + "{                            /n"  
  29.                     + "   v_Color = a_Color;"  
  30.                     + "   v_texCoords = a_texCoords;/n"  
  31.                     + "   gl_Position =   a_Position;  /n"  
  32.                     + "}                            /n";  
  33.             String fragmentShader = "precision mediump float;/n"  
  34.                     + "varying vec4 v_Color;/n"  
  35.                     + "varying vec2 v_texCoords; /n"  
  36.                     + "uniform sampler2D u_texture;/n"  
  37.                     +  
  38.                     "void main()                                  /n"  
  39.                     + "{                                            /n"  
  40.                     + "  gl_FragColor = v_Color * texture2D(u_texture, v_texCoords);/n"  
  41.                     + "}";  
  42.             meshShader = new ShaderProgram(vertexShader, fragmentShader);  
  43.             if (meshShader.isCompiled() == false)  
  44.                 throw new IllegalStateException(meshShader.getLog());  
  45.         }  
  46.         public void dispose() {  
  47.         }  
  48.         public void pause() {  
  49.         }  
  50.         public void render() {  
  51.             frameBuffer.begin();  
  52.             Gdx.graphics.getGL20().glViewport(00, frameBuffer.getWidth(),  
  53.                     frameBuffer.getHeight());  
  54.             Gdx.graphics.getGL20().glClearColor(0f, 1f, 0f, 1);  
  55.             Gdx.graphics.getGL20().glClear(GL20.GL_COLOR_BUFFER_BIT);  
  56.             Gdx.graphics.getGL20().glEnable(GL20.GL_TEXTURE_2D);  
  57.             texture.bind();  
  58.             meshShader.begin();  
  59.             meshShader.setUniformi("u_texture"0);  
  60.             mesh.render(meshShader, GL20.GL_TRIANGLES);  
  61.             meshShader.end();  
  62.             frameBuffer.end();  
  63.             Gdx.graphics.getGL20().glViewport(00, Gdx.graphics.getWidth(),  
  64.                     Gdx.graphics.getHeight());  
  65.             Gdx.graphics.getGL20().glClearColor(0.2f, 0.2f, 0.2f, 1);  
  66.             Gdx.graphics.getGL20().glClear(GL20.GL_COLOR_BUFFER_BIT);  
  67.             spriteBatch.begin();  
  68.             spriteBatch.draw(frameBuffer.getColorBufferTexture(), 00256,  
  69.                     25600, frameBuffer.getColorBufferTexture().getWidth(),  
  70.                     frameBuffer.getColorBufferTexture().getHeight(), false,  
  71.                     true);  
  72.             spriteBatch.end();  
  73.         }  
  74.         public void resize(int width, int height) {  
  75.         }  
  76.         public void resume() {  
  77.         }  
  78.     }  
  79.     public void onCreate(Bundle bundle) {  
  80.         super.onCreate(bundle);  
  81.         // 初始化遊戲屏幕,並設置是否支持GLES 2.0,如果您對向下兼容沒什麼需要選擇true即可(2.1以上),否則選擇false。  
  82.         initialize(new TestFrameBuffer(), true);  
  83.     }  
  84. }  

 


關於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外相互間不能組合疊加,事件能否傳遞取決於上級組件是否設置了相關監聽)

 

[java] view plaincopy
  1. //Libgdx中Actor的使用  
  2. public class Main extends AndroidApplication {  
  3.     class TestActor implements ApplicationListener {  
  4.         Stage stage;  
  5.         public void create() {  
  6.             //構建等值於屏幕大小的場景  
  7.             stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);  
  8.             // 構建Button  
  9.             Button btn = new Button("btn1", TextureDict.loadTexture("myButton.png")  
  10.                     .get()) {  
  11.                 // PS:因爲Libgdx的touchDown有內部實現,所以重載touchDown時必須調用super方法(肯定沒LGame方便啦^^~)  
  12.                 protected boolean touchDown(float x, float y, int pointer) {  
  13.                     super.touchDown(x, y, pointer);  
  14.                     Gdx.app.log("click""x:"+x+",y:"+y);  
  15.                     return true;  
  16.                 }  
  17.             };  
  18.             btn.x = 55;  
  19.             btn.y = 55;  
  20.             stage.addActor(btn);  
  21.             // 注入Stage監聽,讓Stage響應窗體事件,必須。(否則無論注入Stage什麼Actor都不會響應事件)  
  22.             Gdx.input.setInputProcessor(stage);  
  23.         }  
  24.         public void dispose() {  
  25.             stage.dispose();  
  26.         }  
  27.         public void pause() {  
  28.         }  
  29.         public void render() {  
  30.             // 繪製stage到屏幕  
  31.             stage.render();  
  32.             // PS:Libgdx無論遊戲業務或遊戲繪圖刷新都經過render  
  33.             // 傳遞屏幕刷新時間給stage,以執行內部業務操作,如果沒有這步,則所有注入Stage中Actor的act方法無法執行  
  34.             stage.act(Gdx.graphics.getDeltaTime());  
  35.         }  
  36.         public void resize(int width, int height) {  
  37.         }  
  38.         public void resume() {  
  39.         }  
  40.     }  
  41.     public void onCreate(Bundle bundle) {  
  42.         super.onCreate(bundle);  
  43.         // 初始化遊戲屏幕,並設置是否支持GLES 2.0,如果您對向下兼容沒什麼需要選擇true即可(2.1以上),否則選擇false。  
  44.         initialize(new TestActor(), true);  
  45.     }  
  46. }  

 

[java] view plaincopy
  1. //Libgdx中Action的使用  
  2. public class Main extends AndroidApplication {  
  3.     class TestAction implements ApplicationListener {  
  4.         Stage stage;  
  5.         Texture texture;  
  6.         public void create() {  
  7.             // 構建場景  
  8.             stage = new Stage(Gdx.graphics.getWidth(),  
  9.                     Gdx.graphics.getHeight(), false);  
  10.             // 構建紋理  
  11.             texture = new Texture(Gdx.files.internal("myImage.png"));  
  12.             texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);  
  13.             // 構建圖像精靈  
  14.             Image img = new Image("actor", texture);  
  15.             img.width = img.height = 100;  
  16.             img.x = img.y = 100;  
  17.             // 依次讓圖像使用下列動作(PS:“$”符號爲調用對應Action類的靜態函數名,就那麼起的罷了(不過有緩存)……)  
  18.             img.action(Forever.$(Sequence.$(ScaleTo.$(1.1f, 1.1f, 0.3f),  
  19.                     ScaleTo.$(1f, 1f, 0.3f))));  
  20.             stage.addActor(img);  
  21.         }  
  22.         public void render() {  
  23.             Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);  
  24.             stage.act(Gdx.graphics.getDeltaTime());  
  25.             stage.render();  
  26.         }  
  27.         public void dispose() {  
  28.             texture.dispose();  
  29.             stage.dispose();  
  30.         }  
  31.         public void pause() {  
  32.         }  
  33.         public void resize(int width, int height) {  
  34.         }  
  35.         public void resume() {  
  36.         }  
  37.     }  
  38.     public void onCreate(Bundle bundle) {  
  39.         super.onCreate(bundle);  
  40.         // 初始化遊戲屏幕,並設置是否支持GLES 2.0,如果您對向下兼容沒什麼需要選擇true即可(2.1以上),否則選擇false。  
  41.         initialize(new TestAction(), true);  
  42.     }  
  43. }  

 


就目前來說,Libgdx可用的遊戲組件相對比較稀少,部分功能或者需要用戶自行實現。不過最近有一位網名moritz的手機遊戲“半全職”開發者(因爲他自己說手機遊戲並不是他唯一的收入來源)已經加入Libgdx項目,未來將重點改進Libgdx的scene2d部分,鑑於Libgdx作者爲此特意寫了一篇名爲“welcome moritz”的博文,moritz此人應該是有一定能力的傢伙,對於Lingdx未來表現大約還是值得期待的(話說,莫非moritz只對改造Libgdx的2D模塊有興趣?Libgdx作者博文中提到目前moritz開發的3D遊戲沒有使用Libgdx——那啥,先把3D組件部分做出來吧,現在是NULL啊……)。

 

在Libgdx的SVN,也有一些具體的遊戲示例,大家可以下載後親身體驗其效果。

 

00


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運行速度判定其性能,否則很容易產生誤判(也不建議用性能不好的真機運行)

 

————————————————————




原文鏈接:http://blog.csdn.net/cping1982/article/details/6176191

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章