サイトのトップへ戻る

libGDX ドキュメント 日本語訳

起動クラスと設定

対象とする各プラットフォームごとに、起動クラスを記述する必要があります。 このクラスでは、バックエンドで動くApplication固有の実装と、アプリケーションのロジックを実装するApplicationListenerのインスタンスを作成します。 起動クラスはプラットフォームごとに違っています。各バックエンドでインスタンスを作成して設定する方法を見てみましょう。

この記事では、あなたが既にプロジェクトの設定、実行、デバッグの説明に従って作業を完了し、 生成されたコアプロジェクト、デスクトップ用プロジェクト、Android用プロジェクト、HTML5プロジェクトをEclipseにインポートしているものと想定しています。



デスクトップ (LWJGL)

my-gdx-game内にあるMain.javaクラスを開くと以下の内容が表示されます:

package com.me.mygdxgame;

import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;

public class Main {
   public static void main(String[] args) {
      LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
      cfg.title = "my-gdx-game";
      cfg.useGL30 = false;
      cfg.width = 480;
      cfg.height = 320;

      new LwjglApplication(new MyGdxGame(), cfg);
   }
}

最初の行では、LwjglApplicationConfiguration のインスタンスを作成しています。 このクラスでは、初期画面の解像度、OpenGL ES 2.0 や 3.0 (Experimental)を使用するかどうかなど、各種構成設定を指定できます。 詳細情報についてはこのクラスの Javadocs を参照してください。

configuration オブジェクトの設定が済んだら、LwjglApplication のインスタンスを作成します。 MyGdxGame() クラスは、ゲームのロジックを実装した ApplicationListener です。

その後ウィンドウが作成され、 ライフサイクルで説明したようにApplicationListenerが起動されます。



デスクトップ (LWJGL3)

準備中...



Android

Android アプリケーションはmain()メソッドをエントリポイントとして使用しませんが、代わりに Activityが必要です。 my-gdx-game-android プロジェクト内の MainActivity.javaクラスを開いてください:

package com.me.mygdxgame;

import android.os.Bundle;

import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;

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

        AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();

        initialize(new MyGdxGame(), cfg);
    }
}

Activityの onCreate() メソッドが、エントリポイントとなるmain メソッドの役目を果たします。 MainActivityAndroidApplicationを継承しており、そのAndroidApplicationActivityを継承しているので覚えておいてください。 デスクトップの起動クラスと同じように。 configuration インスタンス (AndroidApplicationConfiguration)を作成します。 設定が済んだら、 設定情報とApplicationListenerであるMyGdxGameを引数として渡してAndroidApplication.initialize() メソッドを実行します。 どういった構成設定が使用できるかの詳細情報については、 AndroidApplicationConfiguration Javadocsを参照してください。

Android アプリケーションでは複数のActivityを使用することができます。 Libgdx 製のゲームは通常一つのActivityのみで作成するようにしてください。 libgdxには、Activityを分けなくても異なる画面を切り替えられる処理が実装されています。 これは、新規にActivityを作成すると必然的に新規OpenGLコンテキストも作成することになるためです。 それだと時間がかかるうえに多くのグラフィックリソースを再読み込みする必要がでてきてしまいます。



libgdxベースのFragment

Android SDK では、特定の画面一部のコントローラーを作成するためのAPIが導入されました。これにより、複数の画面で画面パーツの使い回しが簡単にできます。 この API は Fragments APIと呼ばれています。 Libgdx もFragment内の画面の一部として使用できます。 Libgdx fragmentを作成するには、AndroidFragmentApplication のサブクラスを作って以下のような初期化処理を行うonCreateView()を実装します:

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return initializeForView(new MyGdxGame());
    }

このコードを正常に動かすには、 -android projectへ他にいくつか変更が必要です。:

  • 1. まだ追加していない場合は、 Android V4 Support Library を -android project とそのビルドパスに追加してください。これは、後で FragmentActivity を継承するために必要です。
  • 2. AndroidLauncher アクティビティ を、AndroidApplicationではなく FragmentActivityを継承するように変更します
  • 3. AndroidLauncher アクティビティでAndroidFragmentApplication.Callbacks を実装します
  • 4. Libgdx用のフラグメント実装であるAndroidFragmentApplicationを継承したクラスを作成します。
  • 5. フラグメントの onCreateView メソッド内にinitializeForView()を追加します。
  • 6. 最後に、AndroidLauncher アクティビティの中身を Libgdx のフラグメントに置き換えます。

例えば:

// 2. Change AndroidLauncher activity to extend FragmentActivity, not AndroidApplication
// 3. Implement AndroidFragmentApplication.Callbacks on the AndroidLauncher activity
public class AndroidLauncher extends FragmentActivity implements AndroidFragmentApplication.Callbacks
{
   @Override
   protected void onCreate (Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);

      // 6. Finally, replace the AndroidLauncher activity content with the Libgdx Fragment.
      GameFragment fragment = new GameFragment();
      FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
      trans.replace(android.R.id.content, fragment);
      trans.commit();
   }

   // 4. Create a Class that extends AndroidFragmentApplication which is the Fragment implementation for Libgdx.
   private class GameFragment extends AndroidFragmentApplication
   {
      // 5. Add the initializeForView() code in the Fragment's onCreateView method.
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
      {  return initializeForView(new MyGdxGame());   }
   }


   @Override
   public void exit() {}
}


AndroidManifest.xml ファイル

AndroidApplicationConfiguration以外に、 Android アプリケーションは AndroidプロジェクトのルートディレクトリにあるAndroidManifest.xml ファイルでも設定できます。この設定は以下のようになります:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.me.mygdxgame"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="landscape"
            android:configChanges="keyboard|keyboardHidden|orientation">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


Target Sdk Version

この属性には対象とするAndroidのバージョンを設定します。



Screen Orientation と Configuration Changes

targetSdkVersion属性に加えて、 activityの要素には screenOrientation属性と configChanges属性を常に設定する必要があります。

screenOrientation 属性では、アプリケーション用に画面の縦横向きを固定します。 アプリケーションが横向きモードと縦向きモードの両方で動作する場合はこれを省略してかまいません。

The configChanges attribute is crucial and should always have the values shown above. この属性を設定しないと、物理キーボードが接続状態/非接続状態になる度に、または端末の傾きが変更になった場合にアプリケーションが再起動します。 screenOrientation 属性が省略された場合、libgdx アプリケーションは画面向きの変更を生じさせるApplicationListener.resize()へのコールを受信するようになります。 API クライアントではそれを受けてアプリケーションの再レイアウトをおこなうことができます。



パーミッション

アプリケーションが端末の外部ストレージ(例えばSDカード)に書き込みをできるようにする必要がある場合、インターネットアクセスが必要な場合、バイブレーターを使用する場合、音声録音をしたい場合は、以下のパーミッションをAndroidManifest.xmlファイルに追加する必要があります:

    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.VIBRATE"/>

ユーザーは多くのパーミッションが必要なアプリケーションを普通は怪しく思うので、どのパーミッションを要求するかは賢明に判断してください。

ロック復帰機能を有効にする場合は、AndroidApplicationConfiguration.useWakeLock に trueを設定する必要があります。

ゲームで加速度センサーとコンパスへのアクセスが不要な場合は、AndroidApplicationConfigurationuseAccelerometer フィールドとAndroidApplicationConfigurationフィールドにfalseに設定してこれらを無効にすることをお勧めします。

ゲームでジャイロセンサーが必要な場合は、AndroidApplicationConfiguration内のuseGyroscopeにtrueを設定する必要があります。 (これは電力を節約するために既定では無効になっています)。

アプリケーションのアイコンなどのようなその他の属性を設定する方法の詳細情報についてはAndroid 開発者ガイドを参照してください。



ライブ壁紙

Libgdx にはAndroidの ライブ壁紙を簡単に作成する機能があります。 ライブ壁紙の起動クラスはAndroidLiveWallpaperServiceと呼ばれ、以下がその例になります:

package com.mypackage;

// imports snipped for brevity 

public class LiveWallpaper extends AndroidLiveWallpaperService {
    @Override
    public ApplicationListener createListener () {
        return new MyApplicationListener();
    }

    @Override
    public AndroidApplicationConfiguration createConfig () {
        return new AndroidApplicationConfiguration();
    }

    @Override
    public void offsetChange (ApplicationListener listener, float xOffset, float yOffset, float xOffsetStep, float yOffsetStep,
        int xPixelOffset, int yPixelOffset) {
        Gdx.app.log("LiveWallpaper", "offset changed: " + xOffset + ", " + yOffset);
    }
}

createListener()メソッドと createConfig()メソッドは、ライブ壁紙がpicker内に表示された時やホームスクリーン上で表示された場合に呼び出されます。

offsetChange() メソッドはユーザーが画面をスワイプした時に呼び出され、画面が中央からどれだけ相対移動したかを通知します。 このメソッドは描写スレッドで呼び出されるので、同期処理を行う必要はありません。

起動クラスに加えて、壁紙について記述した XML ファイルを作成する必要があります。 そのファイル名は livewallpaper.xmlとしましょう。Androidプロジェクトのres/フォルダ内にxml/という名前のフォルダを作成して、そのファイルを置きます(res/xml/livewallpaper.xml)。以下がファイルに記述する内容になります:

<?xml version="1.0" encoding="UTF-8"?>
<wallpaper
       xmlns:android="http://schemas.android.com/apk/res/android"  
       android:thumbnail="@drawable/ic_launcher"
       android:description="@string/description"
       android:settingsActivity="com.mypackage.LivewallpaperSettings"/>

これはpicker内のライブ壁紙を表示するサムネイル、ライブ壁紙に関する説明、ユーザーがライブ壁紙picker内の"Settings"をタップした時に表示されるActivityを定義しています。 ここでは、背景色などのような設定を変更するためのいくつかのウィジットを持つ標準Activityを設定します。 このActicityで変更した設定情報はSharedPreferences内に保存して、後からGdx.app.getPreferences()を使ってライブ壁紙のApplicationListenerに読み込むことができます。

最後にこれらを AndroidManifest.xml ファイルに追加する必要があります。以下は、簡単な settings Activityを付けたライブ壁紙の例です:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.mypackage"
      android:versionCode="1"
      android:versionName="1.0"
      android:installLocation="preferExternal">
    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="14"/> 
    <uses-feature android:name="android.software.live_wallpaper" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".LivewallpaperSettings" 
                  android:label="Livewallpaper Settings"/>

        <service android:name=".LiveWallpaper"
            android:label="@string/app_name"
            android:icon="@drawable/icon"
            android:permission="android.permission.BIND_WALLPAPER">
            <intent-filter>
                <action android:name="android.service.wallpaper.WallpaperService" />
            </intent-filter>
            <meta-data android:name="android.service.wallpaper"
                android:resource="@xml/livewallpaper" />
        </service>                  
    </application>
</manifest> 

このマニフェストでは以下を定義しています:

  • ライブ壁紙機能を使用すること。 <uses-feature>の部分を参照。
  • 壁紙の紐付けを許可する権限。 android:permissionの部分を参照。
  • 壁紙設定用アクティビティ
  • livewallpaper.xml ファイルを参照する livewallpaper サービス。meta-dataの部分を参照。

ライブ壁紙はAndroid 2.1 (SDK level 7)以降でのみサポートを開始しているので注意してください。

ライブ壁紙にはタッチ入力に関するいくつかの制限があります。通常はタップ/ドロップのみしか通知されません。 タッチ機能を全ての使用したい場合は、AndroidApplicationConfiguration#getTouchEventsForLiveWallpaperフラグをtrueにするとマルチタッチイベントを全て受信できます。



Daydream

Android 4.2から、ユーザーは端末が待機状態やドック画面になった場合に表示されるDaydreams を設定できるようになりました。 これらDaydreamはスクリーンセーバーのようなもので、写真アルバムなどを表示することができます。 Libgdx ではそうした daydreams などを簡単に記述できます。

Daydream の起動クラスは AndroidDaydreamと呼ばれます。以下がその例です:

package com.badlogic.gdx.tests.android;

import android.annotation.TargetApi;
import android.util.Log;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.badlogic.gdx.backends.android.AndroidDaydream;
import com.badlogic.gdx.tests.MeshShaderTest;

@TargetApi(17)
public class Daydream extends AndroidDaydream {
   @Override
   public void onAttachedToWindow() {
      super.onAttachedToWindow();      
      setInteractive(false);

      AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
      ApplicationListener app = new MeshShaderTest();
      initialize(app, cfg);
   }
}

AndroidDaydreamを継承して onAttachedToWindowを上書きし、configurationと ApplicationListener を設定して daydreamを初期化するだけです。

daydream自身に加えて、ユーザーがdaydreamを設定できるようにする設定用アクティビティを用意することができます。 これには普通のactivityやlibgdx のAndroidApplicationが使用できます。以下が、雛形となる空activity の例です:

package com.badlogic.gdx.tests.android;

import android.app.Activity;

public class DaydreamSettings extends Activity {

}

この設定用アクティビティは、Daydream サービスにメタデータとして設定する必要があります。 Androidプロジェクトのres/xmlフォルダ内でxmlファイルを作成して、以下のようなactivityを設定してください:

<dream xmlns:android="http://schemas.android.com/apk/res/android"
 android:settingsActivity="com.badlogic.gdx.tests.android/.DaydreamSettings" />

最後に、いつものように AndroidManifest.xmlにsettings activityの項目とdaydreamに関するサービス説明を追加してください。以下のように:

<service android:name=".Daydream"
   android:label="@string/app_name"
   android:icon="@drawable/icon"
   android:exported="true">
   <intent-filter>
       <action android:name="android.service.dreams.DreamService" />
       <category android:name="android.intent.category.DEFAULT" />
   </intent-filter>
   <meta-data android:name="android.service.dream"
       android:resource="@xml/daydream" />
</service>


iOS/Robovm

準備中..



HTML5/GWT

HTML5/GWT アプリケーションのメインエントリーポイントは GwtApplicationです。my-gdx-game-html5プロジェクト内の GwtLauncher.java を開いてください:

package com.me.mygdxgame.client;

import com.me.mygdxgame.MyGdxGame;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.backends.gwt.GwtApplication;
import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration;

public class GwtLauncher extends GwtApplication {
   @Override
   public GwtApplicationConfiguration getConfig () {
      GwtApplicationConfiguration cfg = new GwtApplicationConfiguration(480, 320);
      return cfg;
   }

   @Override
   public ApplicationListener createApplicationListener () {
      return new MyGdxGame();
   }
}

メインエントリーポイントは GwtApplication.getConfig()GwtApplication.createApplicationListener()という二つのメソッドで構成されています。 GwtApplication.getConfig()メソッドを上書きする際には、HTML5アプリケーションの様々な構成設定を師弟したGwtApplicationConfigurationインスタンスを戻り値として返す必要があります。 GwtApplication.createApplicatonListener()メソッドを上書きする際には、実行するための ApplicationListener を戻り値として返す必要があります。



Module Files

GWT では参照する各 jar/project ごとに実際の Java コードが必要です。さらに、これらの各 jars/project にはファイル名の末尾が gwt.xmlとなっているモジュール定義ファイルを持っている必要があります。

例えばプロジェクトの設定では、 html5 project のモジュールファイルは以下のようになります:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit trunk//EN" "http://google-web-toolkit.googlecode.com/svn/trunk/distro-source/core/src/gwt-module.dtd">
<module>
   <inherits name='com.badlogic.gdx.backends.gdx_backends_gwt' />
   <inherits name='MyGdxGame' />
   <entry-point class='com.me.mygdxgame.client.GwtLauncher' />
   <set-configuration-property name="gdx.assetpath" value="../my-gdx-game-android/assets" />
</module>

この設定では、開始点クラスとhtml5 projectのルートディレクトリへの相対パス(assetsディレクトリを指している)だけではなく、継承元となっているその他二つのモジュール(gdx-backends-gwt と core project)も設定しています。

Both the gdx-backend-gwt jar and the core project have a similar module file, specifying other dependencies. モジュールのファイルとソースが含まれていない jars/project を使用することはできません!

モジュールと依存関係の詳細情報については、GWT 開発者ガイドを参照してください。



Javaリフレクションのサポート

様々な理由から、GWT では Java リフレクションをサポートしていません。 Libgdx は、選ばれた小数の内部クラスについて、リフレクション情報を生成をする内部エミュレーションレイヤを持っています。 つまり、libgdxのJson のシリアライズ機能を使おうとした場合にこの問題に直面するということです。 リフレクション情報を生成するパッケージとクラスを指定することで、この問題を回避できます。 これを行うためには、GWTプロジェクトのgwt.xmlファイルに以下のような設定プロパティを記述します:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<module>
    ... other elements ...
    <extend-configuration-property name="gdx.reflect.include" value="org.softmotion.explorers.model" />
    <extend-configuration-property name="gdx.reflect.exclude" value="org.softmotion.explorers.model.HexMap" />
</module>

extend-configuration-property エレメントをさらに追加することで、複数のパッケージやクラスを追加できます。

この機能は試験的に導入されているものなので、ご使用については自己責任でお願いします。



ローディング画面

libgdx HTML5 アプリケーションでは、gdx.assetpathにある全てのゲーム素材を事前に読み込みます。 この読み込み処理の間、GWTウィジットで実装されたローディング画面が表示されます。 このローディング画面をカスタマイズしたい場合は、(上記例のGwtLauncher で)GwtApplication.getPreloaderCallback() メソッドを上書きするだけでできます。 以下の例では、Canvasを使って非常にシンプルで雑なローディング画面を描写しています:

long loadStart = TimeUtils.nanoTime();
public PreloaderCallback getPreloaderCallback () {
  final Canvas canvas = Canvas.createIfSupported();
  canvas.setWidth("" + (int)(config.width * 0.7f) + "px");
  canvas.setHeight("70px");
  getRootPanel().add(canvas);
  final Context2d context = canvas.getContext2d();
  context.setTextAlign(TextAlign.CENTER);
  context.setTextBaseline(TextBaseline.MIDDLE);
  context.setFont("18pt Calibri");

  return new PreloaderCallback() {
     @Override
     public void done () {
        context.fillRect(0, 0, 300, 40);
     }

     @Override
     public void loaded (String file, int loaded, int total) {
        System.out.println("loaded " + file + "," + loaded + "/" + total);
        String color = Pixmap.make(30, 30, 30, 1);
        context.setFillStyle(color);
        context.setStrokeStyle(color);
        context.fillRect(0, 0, 300, 70);
        color = Pixmap.make(200, 200, 200, (((TimeUtils.nanoTime() - loadStart) % 1000000000) / 1000000000f));
        context.setFillStyle(color);
        context.setStrokeStyle(color);
        context.fillRect(0, 0, 300 * (loaded / (float)total) * 0.97f, 70);

        context.setFillStyle(Pixmap.make(50, 50, 50, 1));
        context.fillText("loading", 300 / 2, 70 / 2);
     }

     @Override
     public void error (String file) {
        System.out.println("error: " + file);
     }
  };
}

ローディング画面の表示では、純正GWTの機能のみを使用できます。libgdxのAPIは事前読み込みが完了した後にしか使用できないので注意してください。