Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android游戲 >> Android游戲開發 >> Android游戲引擎libgdx使用教程5:常用UI類與舞台

Android游戲引擎libgdx使用教程5:常用UI類與舞台

編輯:Android游戲開發

       像按鈕、下拉框、列表、標簽、圖片、復選框、編輯框、分割面板、滑動面板、滑動條等都是比較常用的UI類,它們都屬於Actor,可以很方便的納入到舞台的管理中,而且都包含在com.badlogic.gdx.scenes.scene2d.ui包中,

       其實仔細看看UI類的實現代碼不難發現其實它們都是大部分繼承自Widget或者Table,如果需要自定義UI可以繼承以上兩個類(它們繼承自Actor),這裡要說明一下libgdx的布局部分使用了TWL,有興趣的朋友可以去看看。

       在介紹每個控件之前我們先來看一下NinePatch,這是最近的一個比較重大的更新。

       何為NinePatch?其實android原生即有NinePatch類,常在按鈕中使用。

Android游戲引擎libgdx使用教程5:常用UI類與舞台

       如圖,將圖片分成九份。中間部分可以根據需要擴大,使按鈕的大小內容變動不受圖片的限制。

       而在libgdx的NinePatch其實就是九個TextureRegion對象。

       常用的實例化方法有兩個:

       public NinePatch (Texture texture, int left, int right, int top, int bottom)

       public NinePatch (TextureRegion region, int left, int right, int top, int bottom)

       關於其中的四個int型參數如何取值我們可以參考一下源碼:

Java代碼
  1. public NinePatch (TextureRegion region, int left, int right, int top, int bottom) {    
  2. int middleWidth = region.getRegionWidth() - left - right;    
  3. int middleHeight = region.getRegionHeight() - top - bottom;    
  4. this.patches = new TextureRegion[] {new TextureRegion(region, 0, 0, left, top),    
  5. new TextureRegion(region, left, 0, middleWidth, top), new TextureRegion(region, left + middleWidth, 0, right, top),    
  6. new TextureRegion(region, 0, top, left, middleHeight), new TextureRegion(region, left, top, middleWidth, middleHeight),    
  7. new TextureRegion(region, left + middleWidth, top, right, middleHeight),    
  8. new TextureRegion(region, 0, top + middleHeight, left, bottom),    
  9. new TextureRegion(region, left, top + middleHeight, middleWidth, bottom),    
  10. new TextureRegion(region, left + middleWidth, top + middleHeight, right, bottom)};    
  11. }  

       先計算中間部分的寬度和高度。然後開始切圖,首先取頂部的最左邊的那個,即圖中編號1的那塊,然後去它右邊的,然後再右邊的。

       取完最上邊的那行,然後取中間的那行,然後取最後一行的。

       由上自下,由左自右。

       而在繪制時又是如何處理的呢?看源碼:

Java代碼
  1. public void draw (SpriteBatch batch, float x, float y, float width, float height) {    
  2. float centerColumnX = x;    
  3. if (patches[BOTTOM_LEFT] != null)    
  4. centerColumnX += patches[BOTTOM_LEFT].getRegionWidth();    
  5. else if (patches[MIDDLE_LEFT] != null)    
  6. centerColumnX += patches[MIDDLE_LEFT].getRegionWidth();    
  7. else if (patches[TOP_LEFT] != null) //    
  8. centerColumnX += patches[TOP_LEFT].getRegionWidth();    
  9. float rightColumnX = x + width;    
  10. if (patches[BOTTOM_RIGHT] != null)    
  11. rightColumnX -= patches[BOTTOM_RIGHT].getRegionWidth();    
  12. else if (patches[MIDDLE_RIGHT] != null)    
  13. rightColumnX += patches[MIDDLE_RIGHT].getRegionWidth();    
  14. else if (patches[TOP_RIGHT] != null) //    
  15. rightColumnX += patches[TOP_RIGHT].getRegionWidth();    
  16. float middleRowY = y;    
  17. if (patches[TOP_LEFT] != null)    
  18. middleRowY += patches[TOP_LEFT].getRegionHeight();    
  19. else if (patches[TOP_CENTER] != null)    
  20. middleRowY += patches[TOP_CENTER].getRegionHeight();    
  21. else if (patches[TOP_RIGHT] != null) //    
  22. middleRowY += patches[TOP_RIGHT].getRegionHeight();    
  23. float topRowY = y + height;    
  24. if (patches[TOP_LEFT] != null)    
  25. topRowY -= patches[TOP_LEFT].getRegionHeight();    
  26. else if (patches[TOP_CENTER] != null)    
  27. topRowY -= patches[TOP_CENTER].getRegionHeight();    
  28. else if (patches[TOP_RIGHT] != null) //    
  29. topRowY -= patches[TOP_RIGHT].getRegionHeight();    
  30. // Bottom row    
  31. if (patches[BOTTOM_LEFT] != null) batch.draw(patches[BOTTOM_LEFT], x, y, centerColumnX - x, middleRowY - y);    
  32. if (patches[BOTTOM_CENTER] != null)    
  33. batch.draw(patches[BOTTOM_CENTER], centerColumnX, y, rightColumnX - centerColumnX, middleRowY - y);    
  34. if (patches[BOTTOM_RIGHT] != null)    
  35. batch.draw(patches[BOTTOM_RIGHT], rightColumnX, y, x + width - rightColumnX, middleRowY - y);    
  36. // Middle row    
  37. if (patches[MIDDLE_LEFT] != null) batch.draw(patches[MIDDLE_LEFT], x, middleRowY, centerColumnX - x, topRowY - middleRowY);    
  38. if (patches[MIDDLE_CENTER] != null)    
  39. batch.draw(patches[MIDDLE_CENTER], centerColumnX, middleRowY, rightColumnX - centerColumnX, topRowY - middleRowY);    
  40. if (patches[MIDDLE_RIGHT] != null)    
  41. batch.draw(patches[MIDDLE_RIGHT], rightColumnX, middleRowY, x + width - rightColumnX, topRowY - middleRowY);    
  42. // Top row    
  43. if (patches[TOP_LEFT] != null) batch.draw(patches[TOP_LEFT], x, topRowY, centerColumnX - x, y + height - topRowY);    
  44. if (patches[TOP_CENTER] != null)    
  45. batch.draw(patches[TOP_CENTER], centerColumnX, topRowY, rightColumnX - centerColumnX, y + height - topRowY);    
  46. if (patches[TOP_RIGHT] != null)    
  47. batch.draw(patches[TOP_RIGHT], rightColumnX, topRowY, x + width - rightColumnX, y + height - topRowY);    
  48. }  

       先計算左右欄的寬度,在計算中間和頂部的高度。然後從下自上的繪制。說實話我覺得這段代碼看著很好玩的。

       現在來說說幾個常用的控件的使用吧。先構建一個舞台。

       先來試試Label吧,label是有緩存的,所以替換顯示內容不是用setText方法,而是使用setWrappedText方法。

       代碼如下:

Java代碼
  1. package com.cnblogs.htynkn.listener;    
  2. import com.badlogic.gdx.ApplicationListener;    
  3. import com.badlogic.gdx.Gdx;    
  4. import com.badlogic.gdx.graphics.GL10;    
  5. import com.badlogic.gdx.graphics.g2d.BitmapFont;    
  6. import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;    
  7. import com.badlogic.gdx.scenes.scene2d.Stage;    
  8. import com.badlogic.gdx.scenes.scene2d.actors.Label;    
  9. public class FirstGame implements ApplicationListener {    
  10. private Stage stage;    
  11. Label label;    
  12. @Override    
  13. public void create() {    
  14. stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),    
  15. true);    
  16. label = new Label("fpsLabel", new BitmapFont(Gdx.files.internal("cf.fnt"),Gdx.files.internal("cf.png"),false), "label1");    
  17. label.x=5;    
  18. label.y=Gdx.graphics.getHeight()-label.height-5;    
  19. stage.addActor(label);    
  20. Gdx.input.setInputProcessor(stage);    
  21. }    
  22. @Override    
  23. public void dispose() {    
  24. stage.dispose();    
  25. }    
  26. @Override    
  27. public void pause() {    
  28. // TODO Auto-generated method stub    
  29. }    
  30. @Override    
  31. public void render() {    
  32. Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);    
  33. label.setWrappedText("FPS: "+Gdx.graphics.getFramesPerSecond(),    
  34. HAlignment.CENTER);    
  35. stage.act(Gdx.graphics.getDeltaTime());    
  36. stage.draw();    
  37. }    
  38. @Override    
  39. public void resize(int width, int height) {    
  40. // TODO Auto-generated method stub    
  41. }    
  42. @Override    
  43. public void resume() {    
  44. // TODO Auto-generated method stub    
  45. }    
  46. }  

       效果:

Android游戲引擎libgdx使用教程5:常用UI類與舞台

       然後再看看Button吧,實例化需要一個ButtonStyle,定義了按鈕三種狀態對應的圖片樣式,按下和松開時的X,Y偏移還有Button中文字繪制所需的BitmapFont和Color。

       按鈕的三種狀態的圖片我就省了,只用一張圖片。

Android游戲引擎libgdx使用教程5:常用UI類與舞台

       修改代碼如下:

Java代碼
  1. package com.cnblogs.htynkn.listener;    
  2. import com.badlogic.gdx.ApplicationListener;    
  3. import com.badlogic.gdx.Gdx;    
  4. import com.badlogic.gdx.graphics.Color;    
  5. import com.badlogic.gdx.graphics.GL10;    
  6. import com.badlogic.gdx.graphics.Texture;    
  7. import com.badlogic.gdx.graphics.g2d.BitmapFont;    
  8. import com.badlogic.gdx.graphics.g2d.NinePatch;    
  9. import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;    
  10. import com.badlogic.gdx.scenes.scene2d.Stage;    
  11. import com.badlogic.gdx.scenes.scene2d.actors.Label;    
  12. import com.badlogic.gdx.scenes.scene2d.ui.Button;    
  13. import com.badlogic.gdx.scenes.scene2d.ui.Button.ButtonStyle;    
  14. public class FirstGame implements ApplicationListener {    
  15. private Stage stage;    
  16. Label label;    
  17. Texture texture;    
  18. Button button;    
  19. @Override    
  20. public void create() {    
  21. stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),    
  22. true);    
  23. texture = new Texture(Gdx.files.internal("06.png"));    
  24. NinePatch n1 = new NinePatch(texture, 7, 7, 9, 9);    
  25. BitmapFont bitmapFont = new BitmapFont(Gdx.files.internal("cf.fnt"),    
  26. Gdx.files.internal("cf.png"), false);    
  27. label = new Label("fpsLabel", bitmapFont, "label1");    
  28. label.x = 5;    
  29. label.y = Gdx.graphics.getHeight() - label.height - 5;    
  30. stage.addActor(label);    
  31. button = new Button("button", new ButtonStyle(n1, n1, n1, 0f, 0f, 0f,    
  32. 0f, bitmapFont, new Color(1, 1, 0, 0.5f)), "button");    
  33. button.x=10;    
  34. button.y=10;    
  35. button.width=100f;    
  36. button.height=32f;    
  37. stage.addActor(button);    
  38. Gdx.input.setInputProcessor(stage);    
  39. }    
  40. @Override    
  41. public void dispose() {    
  42. stage.dispose();    
  43. }    
  44. @Override    
  45. public void pause() {    
  46. // TODO Auto-generated method stub    
  47. }    
  48. @Override    
  49. public void render() {    
  50. Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);    
  51. label.setWrappedText("FPS: " + Gdx.graphics.getFramesPerSecond(),    
  52. HAlignment.CENTER);    
  53. stage.act(Gdx.graphics.getDeltaTime());    
  54. stage.draw();    
  55. }    
  56. @Override    
  57. public void resize(int width, int height) {    
  58. // TODO Auto-generated method stub    
  59. }    
  60. @Override    
  61. public void resume() {    
  62. // TODO Auto-generated method stub    
  63. }    
  64. }  

       效果:

Android游戲引擎libgdx使用教程5:常用UI類與舞台

       按鈕自然應該有點擊事件,通過setClickListener來設置:

Java代碼
  1. button.setClickListener(new ClickListener() {    
  2. @Override    
  3. public void click(Actor actor) {    
  4. Gdx.app.log("Info", "點擊事件觸發了");    
  5. }    
  6. });  

       然後再看看CheckBox。CheckBox的樣式定義在CheckBoxStyle中,需要4個參數,兩種狀態的各一張圖片,一個BitmapFont和Color。

       這裡我再添加一張圖片:

Android游戲引擎libgdx使用教程5:常用UI類與舞台

       原理差不多,直接貼代碼了。

Java代碼
  1. package com.cnblogs.htynkn.listener;    
  2. import android.graphics.Paint.Align;    
  3. import com.badlogic.gdx.ApplicationListener;    
  4. import com.badlogic.gdx.Gdx;    
  5. import com.badlogic.gdx.graphics.Color;    
  6. import com.badlogic.gdx.graphics.GL10;    
  7. import com.badlogic.gdx.graphics.Texture;    
  8. import com.badlogic.gdx.graphics.g2d.BitmapFont;    
  9. import com.badlogic.gdx.graphics.g2d.NinePatch;    
  10. import com.badlogic.gdx.graphics.g2d.TextureRegion;    
  11. import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;    
  12. import com.badlogic.gdx.scenes.scene2d.Actor;    
  13. import com.badlogic.gdx.scenes.scene2d.Stage;    
  14. import com.badlogic.gdx.scenes.scene2d.actors.Label;    
  15. import com.badlogic.gdx.scenes.scene2d.ui.Button;    
  16. import com.badlogic.gdx.scenes.scene2d.ui.CheckBox;    
  17. import com.badlogic.gdx.scenes.scene2d.ui.ClickListener;    
  18. import com.badlogic.gdx.scenes.scene2d.ui.Button.ButtonStyle;    
  19. import com.badlogic.gdx.scenes.scene2d.ui.CheckBox.CheckBoxStyle;    
  20. public class FirstGame implements ApplicationListener {    
  21. private Stage stage;    
  22. Label label;    
  23. Texture texture1;    
  24. Texture texture2;    
  25. CheckBox checkBox;    
  26. @Override    
  27. public void create() {    
  28. stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),    
  29. true);    
  30. texture1 = new Texture(Gdx.files.internal("06.png"));    
  31. texture2 = new Texture(Gdx.files.internal("07.png"));    
  32. NinePatch n1 = new NinePatch(texture1, 7, 7, 9, 9);    
  33. BitmapFont bitmapFont = new BitmapFont(Gdx.files.internal("cf.fnt"),    
  34. Gdx.files.internal("cf.png"), false);    
  35. label = new Label("fpsLabel", bitmapFont, "label1");    
  36. label.x = 5;    
  37. label.y = Gdx.graphics.getHeight() - label.height - 5;    
  38. CheckBoxStyle style = new CheckBoxStyle(new TextureRegion(texture1),    
  39. new TextureRegion(texture2), bitmapFont, new Color(1, 1, 1,    
  40. 0.5f));    
  41. checkBox = new CheckBox("checkbox", style, "checkbox");    
  42. checkBox.x = 100;    
  43. checkBox.y = 100;    
  44. checkBox.width = 158f;    
  45. checkBox.height = 32f;    
  46. checkBox.setText("Yes");    
  47. checkBox.setClickListener(new ClickListener() {    
  48. @Override    
  49. public void click(Actor actor) {    
  50. if (checkBox.isChecked) {    
  51. checkBox.setText("Yes");    
  52. } else {    
  53. checkBox.setText("NO");    
  54. }    
  55. }    
  56. });    
  57. stage.addActor(checkBox);    
  58. stage.addActor(label);    
  59. Gdx.input.setInputProcessor(stage);    
  60. }    
  61. @Override    
  62. public void dispose() {    
  63. stage.dispose();    
  64. }    
  65. @Override    
  66. public void pause() {    
  67. // TODO Auto-generated method stub    
  68. }    
  69. @Override    
  70. public void render() {    
  71. Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);    
  72. label.setWrappedText("FPS: " + Gdx.graphics.getFramesPerSecond(),    
  73. HAlignment.CENTER);    
  74. stage.act(Gdx.graphics.getDeltaTime());    
  75. stage.draw();    
  76. }    
  77. @Override    
  78. public void resize(int width, int height) {    
  79. // TODO Auto-generated method stub    
  80. }    
  81. @Override    
  82. public void resume() {    
  83. // TODO Auto-generated method stub    
  84. }    
  85. }  

       效果:

Android游戲引擎libgdx使用教程5:常用UI類與舞台Android游戲引擎libgdx使用教程5:常用UI類與舞台

       其他的UI大致用法差不多,顯示的樣式在對應的Style或者Skin中定義。但是要注意有些UI類需要手動設置width和height,不然有些顯示會很奇怪的。

       最後說一下Slider的用法。

       SliderStyle需要一個NinePath和Texture,我最初沒有想通為什麼不是兩個NinePath,仔細看一下源碼才了解到,NinePath是作為背景,而Texture那個是中間的那個滑動的方塊。

       關於用配置文件設置Style的問題,google code的wiki上似乎沒有寫,但是在libgdx的論壇裡面有,比如:

Java代碼
  1. somePatch1: [   
  2. { height: 13, width: 9, x: 761, y: 78 },   
  3. { height: 13, width: 1, x: 770, y: 78 },   
  4. { height: 13, width: 9, x: 771, y: 78 },   
  5. { height: 1, width: 9, x: 761, y: 91 },   
  6. { height: 1, width: 1, x: 770, y: 91 },   
  7. { height: 1, width: 9, x: 771, y: 91 },   
  8. { height: 13, width: 9, x: 761, y: 92 },   
  9. { height: 13, width: 1, x: 770, y: 92 },   
  10. { height: 13, width: 9, x: 771, y: 92 }   
  11. ]  

       或者

Java代碼
  1. somePatch2: [   
  2. { height: 13, width: 9, x: 761, y: 78 },   
  3. ]  

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved