前面有一篇文章介紹了用TWL進行布局,最近做其他java的東西接觸到了table-layout,用著很不錯,仔細看來一下文檔,原來還支援libgdx。
簡單試用了一下,比TWL好使多了。
TABLELAYOUT簡介
TABLELAYOUT是一個輕量級的UI組件布局庫。使用表格實現,有點像HTML的TABLE。
它支援libgdx, Swing, Android和TWL。支援Java API和設定檔兩種方式。
同時有個配套的編輯器http://table-layout.googlecode.com/svn/wiki/jws/editor.jnlp
使用設定檔
其實最好的方法應該是使用設定檔,這樣便於修改,還可以利用工具進行可視化編輯。但是libgdx對於設定檔的支援好像沒有很到位(或者是版本修改等等問題)。
所以先介紹設定檔方式。設定檔的具體書寫格式請參考table-layout首頁。
開啟編輯器,繪製一個簡單的遊戲介面,包含一個開始按鈕和設定按鈕。
設定檔如下:
debug*spacing:12 padding:5 align:center---[StartButton] width:200 height:60---[PrefButton] width:200 height:60
那個debug是顯示邊框的,方便調試。空間以對應的類型為結尾,比如StartButton就是按鈕。
第二行定義的是全域樣式。還有很多其他樣式可以定義,我個人覺得很Css盒子模型很接近。
將檔案儲存為main.layout。
因為TableLayout是在Stage中使用的,所以很其他的Actor的用法雷同。先添加一個table,在從table中擷取TableLayout。然後定義控制項,並和設定檔中的名字一一對應註冊進去,最後載入設定檔。
先建立一個table並添加到stage中
Table table = new Table(skin);stage.addActor(table);
然後擷取TableLayout
TableLayout layout = table.getTableLayout();
建立控制項以後進行註冊
layout.register("StartButton", StartButton);
其中第一個是設定檔中的名稱,第二個是你代碼中的名稱。
最後載入設定檔
layout.parse(Gdx.files.internal("layout/main.layout").readString());
看一下完整的代碼
package com.cnblogs.htynkn;import com.badlogic.gdx.ApplicationListener;import com.badlogic.gdx.Gdx;import com.badlogic.gdx.graphics.GL10;import com.badlogic.gdx.graphics.g2d.BitmapFont;import com.badlogic.gdx.graphics.g2d.stbtt.TrueTypeFontFactory;import com.badlogic.gdx.scenes.scene2d.Stage;import com.badlogic.gdx.scenes.scene2d.ui.Skin;import com.badlogic.gdx.scenes.scene2d.ui.TextButton;import com.badlogic.gdx.scenes.scene2d.ui.tablelayout.Table;import com.badlogic.gdx.scenes.scene2d.ui.tablelayout.TableLayout;public class App implements ApplicationListener {Stage stage;@Overridepublic void create() {stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),true);Skin skin = new Skin(Gdx.files.internal("skin/uiskin.json"));Table table = new Table(skin);table.width = Gdx.graphics.getWidth();table.height = Gdx.graphics.getHeight();stage.addActor(table);TableLayout layout = table.getTableLayout();TextButton StartButton = new TextButton("Start game", skin);layout.register("StartButton", StartButton);TextButton PrefButton = new TextButton("Settings", skin);layout.register("PrefButton", PrefButton);layout.parse(Gdx.files.internal("layout/main.layout").readString());}@Overridepublic void dispose() {stage.dispose();}@Overridepublic void render() {Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);stage.act(Gdx.graphics.getDeltaTime());stage.draw();}@Overridepublic void resize(int width, int height) {}@Overridepublic void pause() {}@Overridepublic void resume() {}}
運行效果如下:
使用API配置
使用代碼控制其實和設定檔差不多,我比較推薦先用編輯器組建組態檔案,然後在根據設定檔寫代碼。
通過table.defaults()設定全域樣式,就是配置中的第二行。參照剛才的設定檔,我們的代碼應該是:
table.defaults().space(12).align("center").pad(5);
通過table.add()添加
table.add(StartButton).width(200).height(60);
設定檔中的---代碼新起一行,代碼中用table.row()實現。
完整代碼如下:
package com.cnblogs.htynkn;import com.badlogic.gdx.ApplicationListener;import com.badlogic.gdx.Gdx;import com.badlogic.gdx.graphics.GL10;import com.badlogic.gdx.graphics.g2d.BitmapFont;import com.badlogic.gdx.graphics.g2d.stbtt.TrueTypeFontFactory;import com.badlogic.gdx.scenes.scene2d.Stage;import com.badlogic.gdx.scenes.scene2d.ui.Skin;import com.badlogic.gdx.scenes.scene2d.ui.TextButton;import com.badlogic.gdx.scenes.scene2d.ui.tablelayout.Table;public class App implements ApplicationListener {Stage stage;@Overridepublic void create() {stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),true);Skin skin = new Skin(Gdx.files.internal("skin/uiskin.json"));Table table = new Table(skin);table.width = Gdx.graphics.getWidth();table.height = Gdx.graphics.getHeight();table.defaults().space(12).align("center").pad(5);TextButton StartButton = new TextButton("Start game", skin);table.add(StartButton).width(200).height(60);table.row();TextButton PrefButton = new TextButton("Settings", skin);table.add(PrefButton).width(200).height(60);stage.addActor(table);}@Overridepublic void dispose() {stage.dispose();}@Overridepublic void render() {Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);stage.act(Gdx.graphics.getDeltaTime());stage.draw();}@Overridepublic void resize(int width, int height) {}@Overridepublic void pause() {}@Overridepublic void resume() {}}
效果是一樣的:
再談Skin中的中文支援
參考前文使用TTF字型檔實現了中文支援,但是Skin預設支援的是Hiero。
要使用TTF字型檔也可以,不過就不能使用設定檔模式了。
我一般比較偷懶,先讀入設定檔,在建立一個Skin,將其中的Font改成TTF字型檔的Font就可以了。
Skin skin1 = new Skin(Gdx.files.internal("skin/uiskin.json"));Skin skin = new Skin();skin.addResource("default-font", font);TextButtonStyle buttonStyle = skin1.getStyle("default",TextButtonStyle.class);buttonStyle.font = font;skin.addStyle("default", buttonStyle);
效果:
說實話這個效果真心沒有英文看著好,所以推薦還是製作Hiero來用吧。
寫在最後
使用TABLELAYOUT好處相當明顯,它使用邏輯性的表格而不是像素定位,極大的方便了開發。同時也增加了自適應性。而且一次學習可以用到多個地方,比如Android和Swing。
Libgdx是一個相當活躍的項目,很多代碼和包都發生了變化。本部落格的代碼一定是運行成功以後分享給大家的,但是不能保證隨著時間推移它依然有效。比如Skin部分就發生了非常大的變化。
遇到找不到包或者沒有對應方法的時候請先看看官方說明,重要的變動會在聲明中提到的,比如0.96就變動了本文介紹的TABLELAYOUT和SCENCE2D。或者在社區搜尋一下,一般都有人提問。
本文使用的Libgdx是0.96發行版...不要使用nightly,變動太多了。
參考:http://www.badlogicgames.com/wordpress/?p=2483