2016/10/20

libGDX 環境建構與 HelloWorld


之前開發 Android 遊戲, 因為都是用 Android 原生物件處理,

所以, 開發益智遊戲(如:知識達人、撲克牌系列、數獨)還可以應付,

但對於遊戲有更複雜需求(粒子 特效、碰撞處理、物理引擎、3D、跨平台), 可能就必須仰賴 Game Engine (遊戲引擎) 了,

選擇的遊戲引擎方案有幾種: Unreal Engine(UE)UnityCocoslibGDXAndEngine,

目前我先研究的 Game Engine 是 libGDX,

它除了是跨平台 (Android、iOS、Windows、Linux) 之外,

更重要的是開源、免費、且功能強大,

支援 2D/3D Particle 粒子特效、Physics 物理引擎、... 等,

同時, 提供多種 GUI Tools (2D Particle Editor、3D Particle Editor、Hiero Text Editor) 方便開發,

以下大略介紹一下, 如何在 Android Project 中整合 libGDX,

步驟 1: 到 libGDX 官方下載網頁, 點選 Releases 鏈結, 下載最新的 libGDX 檔案.




步驟 2: 解壓縮後, 將 armeabiarmeabi-v7a 兩個目錄, 複製到 Android Project 底下的 libs 目錄中 :


步驟 3: 開啟 Android Project 的 Properties 畫面, 點選 Java Build Path > Libraries > Add External JARs, 加入 gdx.jargdx-backend-android.jar :


步驟 4: 為了能夠在 Eclipse 中, 查看 gdx 相關套件 API 的說明, 在 Source attachment 選擇 libGDX sources 內對應的 jar 檔案 :


步驟 5: 新增一個繼承 AndroidApplication 的 Class 檔案 :
 程式碼
public class HelloWorld extends AndroidApplication
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setTitle("libGDX 遊戲引擎");
        
        // 取得螢幕寬與長 (用於後續 libGDX 座標轉換用的)
        DisplayMetrics dm = new DisplayMetrics();
        this.getWindowManager().getDefaultDisplay().getMetrics(dm);
        int gScreenWidth  = dm.widthPixels;
        int gScreenHeight = dm.heightPixels;
        
        // libGDX 初始化 & 相關觸發事件
        initialize( new LibGdxListener( gScreenWidth, gScreenHeight ) );
    }
}

查看 AndroidApplication 的繼承關係, 可以看到是繼承 Activity 而來, 這說明了 libGDX 可與 Android 原生元件進行整合 :


步驟 6: 新增一個 libGDX Listener 類別 :
 程式碼
public class LibGdxListener implements ApplicationListener
{
    /** 螢幕寬與長 */
    private int gScreenWidth;
    private int gScreenHeight;
    
    /** 類似 Canvas */
    private SpriteBatch gSBCanvas;
    
    /** 紋理:類似 ImageView */
    private Texture gTexture;
    
    public LibGdxListener( int pScreenWidth, int pScreenHeight )
    {
        this.gScreenWidth  = pScreenWidth;
        this.gScreenHeight = pScreenHeight;
    }
    
    @Override
    public void create()
    {
        gSBCanvas = new SpriteBatch();
        
        // 取得 assets 的圖片
        gTexture = new Texture( Gdx.files.internal("star.png"));
    }
    
    /* 渲染處理 */
    @Override
    public void render()
    {
        // 清除全螢幕的模式:
        // GL_ALPHA_BITS: 完全透明
        // GL_COLOR_BUFFER_BIT: 顏色填充
        Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT );
        
        // 清除全螢幕的顏色 (用某個顏色填充整個螢幕) (參數:R,G,B,A; 參數值:0~1)
        Gdx.gl.glClearColor(0.2f, 1f, 1f, 0f);
        
        // ------------------
        // 繪圖前, 必須執行此行, 否則會出錯
        // ------------------
        gSBCanvas.begin();
        
        // ------------------
        // 開始繪圖
        // ------------------
        // 注意: libGDX Y 軸座標是從【左下角】算起, 而非左上角算起
        // 所以會顯示在左下角
        gSBCanvas.draw( gTexture, 20, 20 );
        
        // 將【libGDX Y 軸座標】轉換成【Mobile Y 軸座標】, 才會顯示在左上角
        gSBCanvas.draw( gTexture, 20, convertY(20, gTexture) );
        
        // ------------------
        // 繪圖後, 必須執行此行, 否則會出錯
        // ------------------
        gSBCanvas.end();
    }
    
    @Override
    public void resize(int arg0, int arg1) {
    }
    
    @Override
    public void pause() {
    }
    
    @Override
    public void resume() {
    }
    
    /* Activity Destroyed 時執行此 method */
    @Override
    public void dispose()
    {
        // 釋放資源
        gSBCanvas.dispose();
        gTexture.dispose();
    }
    
    /** 功能: 轉換 Y 軸座標
     * @param pOriginalY :libGDX Y 軸座標
     * @param pTexture :紋理
     * @return 傳回 Mobile Y 軸座標
     */
    private int convertY( int pOriginalY, Texture pTexture )
    {
        return gScreenHeight - pTexture.getHeight() - pOriginalY;
    }
}

範例結果, 如下 :


對於 libGDX 遊戲引擎的相關研究, 後續再一一分享.