針對不同的平臺,啟動類需要被重寫,該啟動類實例化不同平臺特定的 Application&ApplicationListener 實現,啟動類是平臺相關的,讓我們來深入了解下如何為 不同的平臺創建和配置 啟動類.
當然,在學習這篇文章時,你也可以事先了解下 Project Setup, Running & Debugging
桌面應用 Desktop (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(處于實驗中)等。 有關更多信息,請參閱此類的Javadocs。
桌面應用 Desktop (LWJGL3)
To come...
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);
}
}
Android 主要的入口方法是Activity的onCreate()方法。 請注意,MainActivity源自AndroidApplication,它本身來自“Activity”。 和桌面啟動器類一樣,創建一個配置實例(AndroidApplicationConfiguration)。 配置完成后,將調用AndroidApplication.initialize()方法,并將(AndroidApplicationConfiguration,MyGdxGame)作為參數進行傳遞。 有關可用的配置設置的更多信息,請參閱AndroidApplicationConfiguration 的Javadocs。
Android應用程序可以有多個Activity。 Libgdx游戲通常只能由一個Activity組成。 游戲的不同screens (屏幕)由libgdx的相關方法進行實現,而不是單獨的Activity。 這樣做的原因是,創建一個新的Activity也意味著創建一個新的OpenGL上下文,這非常耗時(意味著必須重新加載所有圖形資源).
基于片段(Fragment )的libgdx
Android SDK引入了一個API來為屏幕的特定部分創建控制器,可以在多個屏幕上輕松重新使用。 該API稱為Fragments API。 現在Libgdx也可以創建Fragment來用作一個大的screen的一部分。 要創建一個Libgdx片段,需要繼承子類AndroidFragmentApplication,并重寫onCreateView()方法:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return initializeForView(new MyGdxGame());
}
該代碼取決于-android項目的其他一些更改:
- 添加V4支持
- 修改AndroidLauncher 繼承 FragmentActivity 而非(AndroidApplication)
- 在AndroidLauncher 頁面實現AndroidFragmentApplication.Callbacks 回調
- 創建一個擴展AndroidFragmentApplication的類,這是Libgdx的Fragment實現。
- 在Fragment的onCreateView方法中添加initializeForView()代碼。
- 最后,用Libgdx Fragment替換AndroidLauncher activity 中的內容。
例如:
// 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.
public static 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() {}
}
The AndroidManifest.xml File
除了AndroidApplicationConfiguration之外,Android應用程序也通過AndroidManifest.xml文件進行配置,該文件位于Android項目的根目錄中。 這可能看起來像這樣:
<?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>
目標Sdk版本
將其設置為要定位的Android版本。
屏幕方向和配置更改
除了targetSdkVersion之外,應始終設置activity元素的screenOrientation和configChanges屬性。
screenOrientation 屬性指定應用程序的固定方向。 如果應用程序可以同時使用橫向和縱向模式,也可以省略此選項。
configChanges屬性至關重要,應始終包含上面顯示的值(screenOrientation )。 省略此屬性意味著每次物理鍵盤滑出/插入時或如果設備的方向改變時,應用程序將重新啟動。 如果省略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。
如果游戲不需要加速度計或指南針訪問,建議您將AndroidApplicationConfiguration的useAccelerometer和useCompass字段設置為false來禁用這些。
如果您的游戲需要陀螺儀傳感器,則必須在AndroidApplicationConfiguration中將useGyroscope設置為true(默認情況下禁用它,以節省能量)。
有關如何設置其他屬性(如應用程序的圖標)的詳細信息,請參閱Android Developer's Guide 。
動態壁紙
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()方法。
當用戶通過主屏幕上的屏幕滑動時,offsetChange()方法會縮放,并告訴您屏幕偏離中心屏幕的程度。 這個方法將在渲染線程上被調用,所以你不需要同步任何東西。
除了起始類外,您還必須創建一個描述您的壁紙的XML文件,文明給這個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"/>
該xml定義了在選擇器上的縮略圖,當用戶在應用的選擇器中點擊“設置”將顯示 說明及活動。這應該只是一個標準的Activity,它具有幾個小部件來更改背景顏色和類似的設置。您可以將這些設置存儲在SharedPreferences中,并通過Gdx.app.getPreferences()稍后加載到LWPs 的ApplicationListener中。
最后,您需要在AndroidManifest.xml文件中添加一些內容。 以下是一個包含簡單設置界面的LWP的應用例子:
<?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服務指向livewallpaper.xml文件,請參閱 meta-data
請注意,只有Android 2.1(SDK級別7)才支持動態壁紙。
LWP應用對觸摸輸入有一些限制。 一般只有輕觸/點擊才會被上報。 如果您想要全觸摸,您可以設置AndroidApplicationConfiguration#getTouchEventsForLiveWallpaper標志為true,以接收完整的多點觸控事件。
Daydreams
從Android 4.2開始,用戶可以設置Daydreams,如果設備空閑時Daydreams將會顯示。 這些Daydreams類似于屏幕保護程序,可以顯示像相冊等的內容。Libgdx讓我們輕松寫出這樣的Daydreams。
Daydreams的基類是AndroidDaydream,以下是一個Daydreams的簡單實例(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,設置您的配置和ApplicationListener并初始化您的Daydreams。
除了Daydreams之外,您還可以提供設置Activity,讓用戶配置您的Daydreams.這可以是一個正常的Activity,或者一個libgdx的AndroidApplication。 以一個空Activity為例:
package com.badlogic.gdx.tests.android;
import android.app.Activity;
public class DaydreamSettings extends Activity {
}
必須將此設置活動指定為Daydream服務的metadata 。 在Android項目的res / xml文件夾中創建一個xml文件,并指定如下活動:
<dream xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.badlogic.gdx.tests.android/.DaydreamSettings" />
最后,像往常一樣在AndroidManifest.xml中添加一些設置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>
由于暫時不準備涉及HTML5,如需要,后期會進行補充.