martes, 7 de mayo de 2013

Abrir una url usando LibGDX


Cuando hacemos un juego en Android, es muy normal que queramos dar al usuario la posibilidad de abrir una página Web. Por ejemplo, para tratar de convencer a nuestros jugadores de que pierdan un minuto en valorar nuestro trabajo en Google Play.

Abrir una url desde Android no tiene ningún misterio; basta con ejecutar este código desde alguna actividad.

Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(myIntent);
  
Pero, ¿qué pasa si hemos desarrollado nuestro juego con LibGDX? Pues que la librería nos abstrae de la implementación concreta (Android en nuestro caso), por lo que cuando estemos programando una pantalla no tendremos acceso a las clases de Android, ni actividades, ni ninguna de esas historias. Y además, a día de hoy, que yo conozca, la librería no provee ningún método que se encargue de esto.

Una posible solución sería hacer que nuestro juego delegue la acción de abrir la url en el componente encargado de lanzarlo para cada implementación (una actividad para Android, una clase para escritorio...). Para conseguirlo, crearemos una interfaz en el proyecto principal de nuestro juego, que declarará el método para abrir una url.

public interface IOperations {
 public void openUrl(String url);
}

A continuación, añadiremos a nuestro juego una atributo de tipo IOperations, y modificaremos el constructor para que requiera este valor como parámetro.

public class MyGame extends Game {

 private IOperations myOperations;
 
 public SaveMeGame(IOperations myOperations){
  this.myOperations = myOperations;
 }
 
 //... Resto de la clase ...
}
 
Ahora podemos agregar a la clase MyGame un método que delegue en IOperations la apertura de la url.

public void openUrl(String url){
 myOperations.openUrl(url);
}
 
Una vez hecho esto, tendremos que modificar los lanzadores de las distintas tecnologías (Android, HTML5, J2SE...) para implementar la interfaz IOperations, y proveer por tanto una implementación concreta del método que abre una url. Para el caso de Android sería algo así.

public class MyActivity extends AndroidApplication implements
  IOperations {

 @Override
 public void onCreate(Bundle savedInstanceState) {
  // ... Preparación del juego ... 

  View gameView = initializeForView(new MyGame(this), config);

  setContentView(gameView);
 }

 @Override
 public void openUrl(String url) {
  Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        startActivity(myIntent);
 }
}

Con esto tendríamos la estructura completa, y podemos usar este método desde cualquier pantalla de nuestro juego.

public class MyScreen implements Screen {

 private final String gameURI = "http://play.google.com/store/apps/details?id=package.game";
 private Game game;

 //... En algún lugar de la pantalla ...
 
 ((MyGame) game).openUrl(gameURI);
 
 //...
}
 
Y eso sería todo. Una vez completado el círculo, un pequeño repaso para asentar la idea.

En nuestra situación de partida estamos escribiendo código en una pantalla de nuestro juego (implementación de Screen), y queremos abrir una url, pero la librería no nos ofrece un método para hacerlo, y la forma de conseguirlo depende de la tecnología en que despleguemos finalmente el juego.

Por tanto, definimos una interfaz IOperations con un método para abrir una url. En esta interfaz podríamos añadir cualquier otro método que necesitemos, y que sea dependiente de la tecnología.

Añadimos a nuestra clase Game un nuevo atributo de tipo IOperations, y modificamos el constructor para que requiera un objeto que implemente la interfaz.

Por último, implementamos la interfaz IOperations en los proyectos correspondientes a cada una de las tecnologías en que vayamos a desplegar nuestro juego. En el ejemplo hemos visto una forma de hacerlo para Android, con la actividad de inicio implementando directamente IOperations. También se podría haber creado una nueva clase que contuviese exclusivamente la implementación de IOperations (y de hecho sería recomendable, sobre todo si empieza a crecer el número de operaciones disponibles).

Y ya podemos invocar el método openUrl sobre una instancia de nuestro juego.

No hay comentarios:

Publicar un comentario

Cualquier aportación será bienvenida