Iniciar y configurar clases - jackgris/wikiLibGDX_es GitHub Wiki

4.3 Iniciar y configurar clases

Para cada plataforma, se debe escribir una clase de arranque. Esta clase crea una instancia de la aplicación específica de la aplicación en el back-end y el ApplicationListener implementa la lógica de la aplicación. Las clases de iniciación son dependientes de la plataforma, vamos a echar un vistazo a cómo crear esas instancias y configurar estas para cada back-end.

En este artículo se asume que ha seguido las instrucciones en Crear, ejecutar, depurar y empaquetar su proyecto y de haber importado los proyectos básico, Desktop, Android y HTML5 generados en Eclipse.

Desktop (LWJGL)

Al abrir la clase Main.java en my-gdx-game podemos ver lo siguiente:

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.useGL20 = false;
      cfg.width = 480;
      cfg.height = 320;

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

Primero realizamos una instancio de LwjglApplicationConfiguration. Esta clase permite especificar varios ajustes de configuración, como la resolución de la pantalla inicial, si desea utilizar OpenGL ES 1.x ó 2.0 y así sucesivamente. Consulte los Javadocs de esta clase para obtener más información.

Una vez que está establecida la configuración en nuestro objeto, se crea una instancia de LwjglApplication. La clase MyGdxGame() es la implementación de el ApplicationListener que tiene la lógica del juego.

A partir de ahí se crea una ventana y el ApplicationListener se invoca como se describe en el Ciclo de vida

Android

Las aplicaciones Android no utilizan el método main() como punto de entrada, si no que requieren una Activity. Al abrir la clase MainActivity.java en el proyecto my-gdx-game-android vamos:

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();
        cfg.useGL20 = false;

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

El método que es el punto de entrada principal es el método del Activity llamado onCreate(). Tenga en cuenta que MainActivity hereda de AndroidApplication, que a su vez hereda de Activity. Al igual que en la clase de arranque de desktop, se crea una instancia de configuración (AndroidApplicationConfiguration). Una vez configurada, se llama al método AndroidApplication.initialize(), pasando en el ApplicationListener, MyGdxGame) , así como la configuración. Consulte el Javadocs de AndroidApplicationConfiguration para más información sobre lo que se dispone en las opciones de configuración.

Las aplicaciones Android pueden tener múltiples activitys. Los juegos en Libgdx por lo general sólo constarán de una sola activity. Las diferentes pantallas del juego se implementan dentro libgdx, no como activitys separadas. La razón de esto es que la creación de una nueva Activity también implica la creación de un nuevo contexto de OpenGL, lo que consume tiempo y también significa que todos los recursos gráficos tienen que ser recargados.

Fragment based libgdx

En el SDK de Android se ha introducido una API para crear controladores para partes específicas de una pantalla, que pueden ser reutilizados fácilmente en múltiples pantallas. Esta API se llama la Fragments API. Libgdx puede ahora también ser usado como una parte de una pantalla más grande, dentro de un Fragment. Para crear un fragment en Libgdx, debe usar la subclase AndroidFragmentApplication e implementar el método onCreateView() con la siguiente inicialización;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Plane plane = (Plane) getArguments().get(ARGS_PLANE);
    return initializeForView(new MyGdxGame());
}

El archivo AndroidManifest.xml

Además del AndroidApplicationConfiguration, una aplicación Android también se configura a través del archivo AndroidManifest.xml, que se encuentra en el directorio raíz del proyecto Android. Esto podría ser algo como esto:

<?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="5" 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

Es crucial especificar el targetSdkVersion en un valor >= 6 se supone que la aplicación se ejecute en versiones de Android superiores a la 1.5. Si este atributo no está establecido, en las versiones de Android más altas se ejecutara la aplicación en modo legacy. La resolución del área de dibujo será más pequeña que la resolución de la pantalla real, una circunstancia indeseable.

Orientación de pantalla y cambios de configuración

Además del targetSdkVersion, siempre se deben establecer los atributos screenOrientation y configChanges de la Activity.

El atributo screenOrientation especifica una orientación fija para la aplicación. Uno puede omitir esto si la aplicación puede trabajar en ambos modos tanto en landscape como en modo portrait.

El atributo configChanges es crucial y debe tener siempre los valores que se muestran arriba. La omisión de este atributo significa que la aplicación se reiniciará cada vez que un teclado físico se deslizó o si la orientación del dispositivo cambia. Si se omite el atributo screenOrientation, una aplicación libgdx recibirá llamadas a ApplicationListener.resize() para indicar el cambio de orientación. Así los clientes del API en consecuencia pueden entonces volver a cambiar la disposición del layout de la aplicación.

Permisos

Si una aplicación tiene que ser capaz de escribir en el almacenamiento externo de un dispositivo (por ejemplo la tarjeta SD), necesita acceso a internet, utiliza el vibrador o quiere grabar audio, los permisos siguientes se deben agregar al archivo 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"/>

Los usuarios suelen desconfiar de las aplicaciones con muchos permisos, por lo que debe optar por estos sabiamente.

Para despertar del bloqueo del dispositivo, AndroidApplicationConfiguration.useWakeLock debe establecerse en true.

Si un juego no necesita acceso al acelerómetro o a la brújula se aconseja desactivar estos estableciendo los campos de AndroidApplicationConfiguration useAccelerometer y useCompass en false.

Por favor, consulte la Guía del desarrollador de Android para obtener más información sobre cómo configurar otros atributos como los iconos para su aplicación.

Live Wallpapers

Libgdx cuenta con una forma fácil de usar para crear Live Wallpapers en Android. La clase de iniciación para un fondo de pantalla vivo se llama AndroidLiveWallpaperService, aquí un ejemplo:

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);
    }
}

Los métodos createListener() y createConfig() se llamarán cuando se muestre el fondo de pantalla vivo en el selector o cuando se crea para mostrarse en la pantalla de inicio.

El método offsetChange() se escala cuando el usuario pasa a través de las pantallas en la pantalla principal y te dice lo mucho que la pantalla está desplazado con respecto al centro de la pantalla. Este método será llamado en el hilo de subproceso del renderizado, por lo que no tiene que sincronizar nada.

Además de una clase de arranque, también hay que crear un archivo XML que describe el fondo de pantalla. Llamemoslo livewallpaper.xml. Cree una carpeta llamada xml/ en la carpeta res/ de su proyecto Android y ponga el archivo ahí (res/xml/livewallpaper.xml). Esto es lo que debe poner en ese archivo:

<?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"/>

Esto define la imagen que se mostrará para su LWP en el selector, la descripción y una actividad que se mostrará cuando el usuario pulsa en "Configuración" en el selector del LWP. Esto debería ser sólo una actividad estándar que tiene un par de widgets para cambiar ajustes tales como el color de fondo y cosas similares. Puede almacenar los ajustes en SharedPreferences y cargarlos más tarde en su procesos ligeros ApplicationListener través Gdx.app.getPreferences().

Por último, tendrá que añadir cosas a su archivo AndroidManifest.xml. He aquí un ejemplo de un LWP con una simple configuración de la actividad:

<?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> 

El manifest define:

  • que caracteristicas utiliza el live wallpaper, ver <uses-feature>.
  • los permiso que se le permitiera unirse al fondo de pantalla, ver el android:permission
  • los ajustes de la activity
  • el servicio livewallpaper, señalando el archivo livewallpaper.xml, vea meta-data

Tenga en cuenta que fondos de pantalla en vivo sólo se admiten a partir de Android 2.1 (nivel del SDK 7).

Los LWPs tienen algunas limitaciones relativas a la entrada táctil. En general se informa sólo el toque/desliz. Si desea táctil completa se puede ver la bandera AndroidApplicationConfiguration#getTouchEventsForLiveWallpaper true para recibir eventos multitáctiles completos.

Daydreams

Desde Android 4.2, los usuarios pueden configurar los Daydreams que consiguen exhibidos si el dispositivo está inactivo o acoplado. Estos Daydreams son similares a protectores de pantalla y pueden mostrar cosas como álbumes de fotos, etc. Con Libgdx vamos a poder escribir esos Daydream fácilmente.

La clase de arranque para un Daydream se llama AndroidDaydream. He aquí un ejemplo:

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();
      cfg.useGL20 = true;
      ApplicationListener app = new MeshShaderTest();
      initialize(app, cfg);
   }
}

Simplemente derivar de AndroidDaydream, sobre escriba el onAttachedToWindow, configure su configuración y el ApplicationListener e inicie su daydream.

Además el propio daydream puede proporcionar una activity de configuración que permite al usuario configurar su daydream. Esto puede ser una activity normal, o un AndroidApplication libgdx. Una activity vacía como un ejemplo:

package com.badlogic.gdx.tests.android;

import android.app.Activity;

public class DaydreamSettings extends Activity {

}

El activity de configuración debe especificarse como metadatos para el servicio del Daydream. Debe crear un archivo XML en la carpeta res/xml de su proyecto Android y especifique el activity como acá:

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

Por último, deb añadir una sección para el activity de los ajustes en el AndroidManifest.xml como es de costumbre, y una descripción del servicio para el Daydream, así:

<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 Xamarin (Deprecated!)

El backend de iOS se basa en el uso de Xamarin MonoDevelop IDE para el desarrollo y una licencia MonoTouch para la implementación. El punto de entrada para una aplicación MonoTouch es el AppDelegate encontrado en el archivo main.cs del proyecto. Un ejemplo de esto es el siguiente:

using System;
using System.Collections.Generic;
using System.Linq;

using MonoTouch.Foundation;
using MonoTouch.UIKit;
using com.badlogic.gdx.backends.ios;
using com.me.mygdxgame;

namespace com.me.mygdxgame
{		
	public class Application
	{
		[Register ("AppDelegate")]
		public partial class AppDelegate : IOSApplication {
			public AppDelegate(): base(new MyGdxGame(), getConfig()) {

			}

			internal static IOSApplicationConfiguration getConfig() {
				IOSApplicationConfiguration config = new IOSApplicationConfiguration();
				config.orientationLandscape = true;
				config.orientationPortrait = false;
				config.useAccelerometer = true;
				config.useMonotouchOpenTK = true;
				config.useObjectAL = true;
				return config;
			}
		}
		
		static void Main (string[] args)
		{
			UIApplication.Main (args, null, "AppDelegate");
		}
	}
}

Info.plist

El archivo Info.plist contiene la información de configuración de la aplicación: orientación de la pantalla, la versión mínima del sistema operativo, los parámetros opcionales, capturas de pantalla, etc. Esto es un archivo XML que es mejor editar a través MonoDevelop.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDisplayName</key>
    <string>my-gdx-game</string>
    <key>MinimumOSVersion</key>
    <string>3.2</string>
    <key>UIDeviceFamily</key>
    <array>
        <integer>2</integer>
        <integer>1</integer>
    </array>
    <key>UIStatusBarHidden</key>
    <true/>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
</dict>
</plist>

convert.properties

Se necesita un proceso de conversión con el fin de crear el assembler necesario para MonoTouch para la plataforma de IOS. Este proceso se hace como parte de la etapa de pre-construcción cuando se emite la operación de generación en MonoDevelop. Si está utilizando bibliotecas de terceros o tiene localizaciones no estándar definidas para algunos de sus fuentes, usted tendrá que actualizar los expediente de convert.properties, en consecuencia. Un ejemplo de archivo es el siguiente:

SRC =       ../my-gdx-game/src/
CLASSPATH = ../my-gdx-game/libs/gdx.jar
EXCLUDE   =
IN        = -r:libs/ios/gdx.dll -recurse:target/*.class
OUT       = target/my-gdx-game.dll

Este archivo especifica los archivos de entrada que componen el my-gdx-game.dll assembly.

HTML5/GWT

El punto de entrada principal para una aplicación HTML5/GWT es GwtApplication. Abra el GwtLauncher.java en el proyecto my-gdx-game-html5.

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 getApplicationListener () {
      return new MyGdxGame();
   }
}

El principal punto de entrada se compone de dos métodos, GwtApplication.getConfig() y GwtApplication.getApplicationListener(). El primero tiene que devolver una instancia de GwtApplicationConfiguration, que especifica varios valores de configuración de la aplicación HTML5. El método GwtApplication.getApplicatonListener() devuelve el ApplicationListener para que funcione.

Archivos de Módulos

GWT necesita el código Java actual para cada jar/proyecto al que se hace referencia. Además, cada uno de estos jar/proyectos deben tener un archivo de definición de módulos, teniendo como subfijo gwt.xml.

En el ejemplo de configuración de proyecto, el archivo del módulo del proyecto html5 se ve así:

<?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>

Especifica otros dos módulos para heredar de (GDX-backends GWT y el proyecto básico), así como la clase de punto de entrada (GwtLauncher arriba) y una ruta relativa al directorio raíz del proyecto html5, que apunta al directorio activo.

Tanto gdx-backend-gwt y el proyecto básico tienen un archivo de módulo similar, especificando otras dependencias. No se puede utilizar jar/proyectos que no contienen un archivo de módulo y los fuentes!

Para obtener más información sobre los módulos y dependencias consulte la Guía del desarrollador GWT.

Soporte para Reflexión

GWT no soporta Java reflexión por varias razones. Libgdx tiene una capa de emulación interna que va a generar la información de reflexión para un selecto grupo de clases internas. Esto significa que si usted utiliza las capacidades de serialización JSON de libgdx, se encontrará con problemas. Puedes solucionar este problema mediante la especificación de qué paquetes y la información de las clases de reflexión que deben ser generadas. Para ello, usted puede poner las propiedades de configuración en el archivo gwt.xml de su proyecto GWT, así:

<?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>

Puede agregar varios paquetes y clases añadiendo más propiedades para extender la configuración de elementos.

Esta característica es experimental, utilicela a su propio riesgo.

Pantalla de carga

Una aplicaciones libgdx HTML5 precarga todos los activos que se encuentran en el gdx.assetpath. Durante este proceso de carga, se muestra una pantalla de carga que se implementa a través del widget de GWT. Si desea personalizar la pantalla de carga, puede simplemente sobrescribir el método (GwtLauncher del ejemplo anterior) GwtApplication.getPreloaderCallback(). El ejemplo siguiente dibuja una pantalla de carga muy simple , fea usando 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);
     }
  };
}

Tenga en cuenta que sólo se pueden utilizar puro GWT para mostrar la pantalla de carga, las APIs de libgdx sólo estarán disponibles después de que la precarga se haya completado.

Enlaces

⚠️ **GitHub.com Fallback** ⚠️