Android専用にlibGDXのプロジェクトを作る

　libGDXはマルチプラットフォーム対応のライブラリなのですが、Android専用で使いたい場合もあると思います。
　既存のプロジェクトの特定のActivityだけlibGDXにしたり、ソーシャルSDKやAndroidの機能をシームレスに遠慮無く使ったり…
　今回は、gdx-setup.jar を使わずにプロジェクトを作ってみましたのでその手順を公開します。


# プロジェクト作成手順

## 最新のlibGDXライブラリをダウンロード
以下のページから `libgdx-nightly-latest.zip` をダウンロード
http://libgdx.badlogicgames.com/nightlies/
![スクリーンショット 2014-05-02 19.02.08trim.png](https://qiita-image-store.s3.amazonaws.com/0/42140/43b8a1e9-69b7-95c8-62c1-d7366421769f.png)



##Androidのプロジェクトを作成
※極普通のプロジェクト作成方法です
Eclipseを起動してメニューの「新規」→「Androidアプリケーションプロジェクト」

![スクリーンショット 2014-05-02 17.11.00.png](https://qiita-image-store.s3.amazonaws.com/0/42140/c3da250d-e915-0941-168f-7a13e02d7db1.png)
ここでは以下の設定でプロジェクトを作成します。

アプリケーション名：GdxAppForAndroidOnly
プロジェクト名：GdxAppForAndroidOnly
パッケージ名：com.dokokano.gdxappforandroidonly


![スクリーンショット 2014-05-02 17.11.54.png](https://qiita-image-store.s3.amazonaws.com/0/42140/02570e11-6ea5-da4e-d8be-d751a7bf503e.png)

![スクリーンショット 2014-05-02 17.11.58.png](https://qiita-image-store.s3.amazonaws.com/0/42140/f8b57e79-8e66-f802-9b37-7be1bf52edb0.png)


![スクリーンショット 2014-05-02 17.23.59.png](https://qiita-image-store.s3.amazonaws.com/0/42140/4c942474-8ee6-82ea-d955-0437ddcb90a7.png)
アクティビティの作成にチェックをいれる
「Blank Activity」を選択

![スクリーンショット 2014-05-02 17.24.07.png](https://qiita-image-store.s3.amazonaws.com/0/42140/78f6192a-1cbc-9ec3-7c30-d513018150a2.png)
これでプロジェクトが作成されます。


![スクリーンショット 2014-05-02 18.36.45.png](https://qiita-image-store.s3.amazonaws.com/0/42140/4d58577d-827c-411d-0232-b48cedcec7b9.png)


##必要なライブラリの追加
ダウンロードしたlibGDXライブラリのアーカイブから必要なライブラリをプロジェクトに追加します。
libgdx-nightly-latest.zipを展開し以下のファイルをプロジェクトのlibsに追加してください。
※ ファイルをEclipseのツリーに直接ドロップしてOKです。

* gdx.jar
* gdx-backend-android.jar
* armeabi (フォルダ)
* armeabi-v7a (フォルダ)
* x86 (フォルダ)

![スクリーンショット 2014-05-02 18.43.06trim.png](https://qiita-image-store.s3.amazonaws.com/0/42140/cded10e3-d647-62a7-fc66-39176bda3a58.png)

　上記のようになればOKです。
　インポートはコピーで行います。
![スクリーンショット 2014-05-02 18.42.44.png](https://qiita-image-store.s3.amazonaws.com/0/42140/0dc0e953-82e4-1423-1072-5310316037b3.png)



##Javaのビルドパスに追加
プロジェクトのプロパティを開き、「Javaのビルドパスを選択」→「ライブラリータブ」→「Jar追加...」ボタン
![スクリーンショット 2014-05-02 18.45.11.png](https://qiita-image-store.s3.amazonaws.com/0/42140/1dc3c90b-3ae5-8458-e7a0-d158e467fb33.png)

以下のJarを追加してください。

* gdx.jar
* gdx-backend-android.jar

![スクリーンショット 2014-05-02 18.46.28.png](https://qiita-image-store.s3.amazonaws.com/0/42140/98c1e852-ef2e-f2b2-6bd1-affac2473dfa.png)


# コードの更新

## MainActivity.javaを書き換え

　プロジェクト作成時に自動生成された `MainActivity.java` を以下のように書き換えてください。（ほとんど入れ替えです）

```java:MainActivity.java
package com.dokokano.gdxappforandroidonly;

import android.os.Bundle;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.badlogic.gdx.graphics.GL20;

public class MainActivity extends AndroidApplication {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();

        initialize(new MyGdxApp(), cfg);
    }

    class MyGdxApp implements ApplicationListener  {
		@Override
		public void create() {
		}

		@Override
		public void dispose() {
		}

		@Override
		public void pause() {
		}

		@Override
		public void render() {
			// 赤で塗りつぶす
			Gdx.gl.glClearColor(1, 0, 0, 1);
			Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		}

		@Override
		public void resize(int width, int height) {
		}

		@Override
		public void resume() {
		}
    }
}
```


## 実行
Androidアプリケーションとして実行してください。
赤い画面が表示されればOKです。
この画面自体、libGDXによって描画されています。
![Screenshot_2014-05-02-18-51-52.png](https://qiita-image-store.s3.amazonaws.com/0/42140/37d61431-7e7c-758a-abcf-6dc0718cd87a.png)


# コードの更新２：機能を強化

　赤い画面ではピンと来ないので画像を表示してみます。

##画像を追加
　画像をプロジェクトに追加します。

http://libgdx.badlogicgames.com/nightlies/config/libgdx-logo.png
上記URLからイメージ「libgdx-logo.png」をダウンロードしてプロジェクトのassetに追加（ファイルをコピー）してください。

![libgdx-logo.png](https://qiita-image-store.s3.amazonaws.com/0/42140/606e0def-f482-ee63-b96a-69970da84cc3.png)
※ 画像のサイズは200x250ピクセルです。



## MainActivity.javaを書き換え

```java:MainActivity.java
package com.dokokano.gdxappforandroidonly;

import android.os.Bundle;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;

public class MainActivity extends AndroidApplication {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();

        initialize(new MyGdxApp(), cfg);
    }

    class MyGdxApp implements ApplicationListener  {
    	// 画面の論理座標
    	static private final float WIDTH  =320;
    	static private final float HEIGHT  =640;

    	// カウンター(renderが呼ばれるたびにカウントアップ）
    	int count;

    	// Gdx用変数
    	OrthographicCamera camera;
    	SpriteBatch batch;
    	Texture texture;
    	Sprite sprite;
    	BitmapFont font;


		@Override
		public void create() {
			// 画面の実際のサイズ(pixel)
			float w = Gdx.graphics.getWidth();
			float h = Gdx.graphics.getHeight();

			// カメラ設定　※画面のサイズにあわせ縦横比が正しい状態で最大限のサイズで設定
			float scrRatio =  w/h;				// 実際の画面の縦横比
			float logicalRatio =  WIDTH /HEIGHT;	// 論理座標の縦横比
			camera = new OrthographicCamera();
			if ( scrRatio>logicalRatio) {
				// 実際の画面のほうが論理座標より横長
				camera.setToOrtho(false, WIDTH/logicalRatio*scrRatio, HEIGHT);
				camera.translate(new Vector2( - (WIDTH/logicalRatio*scrRatio - WIDTH)/2,0));
				camera.update();
			}else{
				// 実際の画面のほうが論理座標より縦長
				camera.setToOrtho(false, WIDTH, HEIGHT*logicalRatio/scrRatio  );
				camera.translate(new Vector2(0,  -(HEIGHT*logicalRatio/scrRatio - HEIGHT)/2));
				camera.update();
			}

			// スプライトバッチ初期化
			batch = new SpriteBatch();

			// フォント初期化
			font = new BitmapFont();

			// テクスチャーをロードしスプライトにセットする
			texture = new Texture(Gdx.files.internal("libgdx-logo.png"));	// 200x250pixel
	       	texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
			TextureRegion region = new TextureRegion(texture, 0, 0, 200, 250);

			sprite = new Sprite(region);
			sprite.setOrigin(sprite.getWidth()/2, sprite.getHeight()/2);				// スプライトの中心を原点に
			sprite.setPosition(WIDTH/2-sprite.getWidth()/2, HEIGHT/2-sprite.getHeight()/2);	// 画面中央に配置
		}

		@Override
		public void dispose() {
			texture.dispose();
			font.dispose();
		}

		@Override
		public void pause() {
		}

		@Override
		public void render() {
			count++;
			// 赤で塗りつぶす
			Gdx.gl.glClearColor(1, 0, 0, 1);
			Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

			// 描画
			batch.setProjectionMatrix(camera.combined);
			batch.begin();

			sprite.setRotation(count);
			sprite.draw(batch);
			font.setColor(Color.WHITE);
			font.draw(batch, "for Android only!", 0, HEIGHT);

			batch.end();
		}

		@Override
		public void resize(int width, int height) {
		}

		@Override
		public void resume() {
		}
    }
}
```

## 実行
![Screenshot_2014-05-02-19-46-02.png](https://qiita-image-store.s3.amazonaws.com/0/42140/c6f1e4df-f225-397f-3ab1-cbe74a44a1d8.png)
画面中央でイメージが回転すれば成功です。




# コードの更新３：Android の機能を呼び出す

## MainActivity.javaに追加

メンバー変数追加

```java
	Handler handler_ = new Handler();
```

render()メソッド内に追加

```java
	// タップされた場合 Toastを表示
	if ( Gdx.input.justTouched()) {
		// Toast表示※Android側の機能を利用
		handler_.post(new Runnable() {
			@Override
			public void run() {
				Toast.makeText(getApplicationContext(), "Touched! (" + count + ")", Toast.LENGTH_SHORT).show();
			}
		});
	}
```

##実行
![Screenshot_2014-05-02-19-51-45.png](https://qiita-image-store.s3.amazonaws.com/0/42140/b66c0f8f-7472-cac8-6e8f-693813e33155.png)

　画面をタップするとToastが表示されます。
　このように直接Androidの機能を呼び出すことができます。
　マルチプラットフォームが不要な場合は、このような形で組み込んでしまうのが効率的かもしれません。


# ソース全体

```java:MainActivity.java
package com.dokokano.gdxappforandroidonly;

import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Vector2;

public class MainActivity extends AndroidApplication {
	Handler handler_ = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
        initialize(new MyGdxApp(), cfg);
    }

    class MyGdxApp implements ApplicationListener  {
    	// 画面の論理座標
    	static private final float WIDTH  =320;
    	static private final float HEIGHT  =640;

    	// カウンター(renderが呼ばれるたびにカウントアップ）
    	int count;

    	// Gdx用変数
    	OrthographicCamera camera;
    	SpriteBatch batch;
    	ShapeRenderer renderer;
    	Texture texture;
    	Sprite sprite;
    	BitmapFont font;


		@Override
		public void create() {
			// 画面の実際のサイズ(pixel)
			float w = Gdx.graphics.getWidth();
			float h = Gdx.graphics.getHeight();

			Gdx.app.log("", "size w:" + w + " h:" + h);

			// カメラ設定　
			// ※画面のサイズにあわせ縦横比が正しい状態で最大限のサイズで設定
			float scrRatio =  w/h;				// 実際の画面の縦横比
			float logicalRatio =  WIDTH /HEIGHT;	// 論理座標の縦横比
			camera = new OrthographicCamera();
			if ( scrRatio>logicalRatio) {
				// 実際の画面のほうが論理座標より横長
				camera.setToOrtho(false, WIDTH/logicalRatio*scrRatio, HEIGHT);
				camera.translate(new Vector2( - (WIDTH/logicalRatio*scrRatio - WIDTH)/2,0));
				camera.update();
			}else{
				// 実際の画面のほうが論理座標より縦長
				camera.setToOrtho(false, WIDTH, HEIGHT*logicalRatio/scrRatio  );
				camera.translate(new Vector2(0,  -(HEIGHT*logicalRatio/scrRatio - HEIGHT)/2));
				camera.update();
			}

			// スプライトバッチ初期化
			batch = new SpriteBatch();
			// レンダラー初期化
			renderer = new ShapeRenderer();

			// フォント初期化
			font = new BitmapFont();

			// テクスチャーをロードしスプライトにセットする
			texture = new Texture(Gdx.files.internal("libgdx-logo.png"));	// 200x250pixel
	       	texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
			TextureRegion region = new TextureRegion(texture, 0, 0, 200, 250);

			sprite = new Sprite(region);
			sprite.setOrigin(sprite.getWidth()/2, sprite.getHeight()/2);				// スプライトの中心を原点に
			sprite.setPosition(WIDTH/2-sprite.getWidth()/2, HEIGHT/2-sprite.getHeight()/2);	// 画面中央に配置
		}

		@Override
		public void dispose() {
			texture.dispose();
			font.dispose();
		}

		@Override
		public void pause() {
		}

		@Override
		public void render() {
			count++;
			// 赤で塗りつぶす
			Gdx.gl.glClearColor(1, 0, 0, 1);
			Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

			// 描画
			batch.setProjectionMatrix(camera.combined);
			batch.begin();
			sprite.setRotation(count);
			sprite.draw(batch);
			font.setColor(Color.WHITE);
			font.draw(batch, "for Android only!", 0, HEIGHT);
			batch.end();

			// 画面の枠を描画（論理座標 WIDTH,HEIGHTの範囲）
			renderer.setProjectionMatrix(camera.combined);
	        renderer.begin(ShapeType.Line);
	        renderer.setColor(1,1,1f,1);
	        renderer.rect(0, 0,WIDTH,HEIGHT);
	        renderer.end();

			// タップされた場合 Toastを表示
			if ( Gdx.input.justTouched()) {
				// Toast表示※Android側の機能を利用
				handler_.post(new Runnable() {
					@Override
					public void run() {
						Toast.makeText(getApplicationContext(), "Touched! (" + count + ")", Toast.LENGTH_SHORT).show();
					}
				});
			}
		}

		@Override
		public void resize(int width, int height) {
		}

		@Override
		public void resume() {
		}
    }
}
```