21/3/14

[Tutorial] Controlador táctil (TouchPad) (libGDX)

Buenas gente!

En esta entrada vamos a ver el método que voy a usar para que mi personaje se desplace por el mapa.

Aunque existen varios métodos como clickar en un punto de la pantalla y que se dirija hacia allí o en esa dirección, tener varios botones que indiquen las posibles direcciones en las que puede moverse, etc., yo voy a usar un TouchPad. Esta herramienta tan útil nos viene ya implementada en libGDX, por lo que su uso es muy sencillo y no hay que escribir apenas código para tenerlo en nuestro juego.

Creando un TouchPad


En mi caso crearé una clase (yo la he llamado Controller) que extienda de la clase TouchPad, para tenerlo todo más modularizado. Veamos las distintas funciones que tendrá esta clase:


##### El constructor #####

En esta función llamaremos al constructor de TouchPad indicándole:
  • El tamaño de la zona central en píxeles. Mientras pulsemos dentro de esta zona no pasará nada.
  • El estilo con el que se dibujará el TouchPad. Esto lo veremos en la siguiente función.

También le indicaremos la posición y el tamaño que tendrá nuestro TouchPad con la función setBounds(...).


##### getTouchPadStyle #####

Aquí crearemos un nuevo Skin touchpadSkin al que le añadiremos:
  • La textura que queramos que tenga de fondo nuestro TouchPad.
  • La textura del elemento que indicará donde estamos pulsando.

Ahora inicializaremos nuestra variable TouchpadStyle touchpadStyle al que le añadiremos los elementos de la Skin que hemos creado antes.

Por último, devolvemos el estilo de nuestro TouchPad, que lo usará en el constructor.


##### act #####

Ya que TouchPad hereda de la clase Actor que vimos en entradas anteriores, podemos sobreeescribir esa función para que, cuando se vaya a actualizar y si lo estás tocando, muevas al personaje.


Añadiendo nuestro TouchPad a la aplicación


Una vez que tenemos nuestro TouchPad con las acciones que queremos que haga, nos queda añadirlo a nuestra aplicación. Para ello primero debemos inicializarlo con el constructor que creamos antes. Luego, ya que es un actor, podremos añadirlo a nuestro Stage (ver más información sobre los Stages y Actores aquí). De esta forma el Stage se encargará de actualizarlo y dibujarlo:


Puedes darle una posición a tu TouchPad con la función:


Y con esto ya tendremos nuestro TouchPad listo y moviendo a nuestro jugador!

Cómo mover al personaje


Para mover a nuestro jugador nuestro TouchPad nos da varias funciones.

Podemos usar las funciones getKnobPercentX() y getKnobPercentY() para saber cuánto está avanzando en cada eje y sumarle esta cantidad a la posición de nuestro personaje. Estas funciones nos darán un valor entre 0 y 1, siendo 0 el valor más cercano al centro y 1 el borde del TouchPad.

Otras funciones son getKnobX() y getKnobY(), que nos devuelven la diferencia en píxeles entre el centro del TouchPad y donde estamos señalando en cada eje.

Puedes ver todas las funciones de esta clase aquí.

Y aquí os muestro capturas de mi aplicación, con el TouchPad abajo a la izquierda. El personaje al que yo manejo es el marrón:



Notas:

  • No te olvides de hacer un dispose() de la Skin.
  • Este TouchPad puede servir tanto para mover a un personaje como para mover la cámara, aumentar el volumen de la música, etc.
  • Para un mayor realismo, puedes calcular el ángulo hacia donde se está moviendo tu personaje y rotarlo hacia ese punto.


Referencias:


12/3/14

[Tutorial] Barras y NinePatch (libGDX)

Buenas gente!

En esta entrada vamos a ver como crear barras de vida, stamina, o cualquier otra variable de nuestro personaje que queramos mostrar. Todo con ayuda, como siempre, de libGDX.

Para hacer esto usaremos una nueva clase: NinePatch que explicaremos con un poco de detalle y nos ayudará a crear las imágenes que necesitamos.

Ninepatch


Para comenzar tendremos que crear nuestra Texture de la cual cogeremos la imagen para nuestra barra. No hace falta que sea una imagen con toda la longitud de la barra, tan solo nos basta con las esquinas, ahora veremos porqué:


Después creamos nuestro NinePatch de la siguiente forma:


Como primer parámetro se le debe pasar una TextureRegion. Puedes crearla aparte o hacer un new directamente como se muestra en la función anterior.

Tras esto se deben indicar 4 valores: left, right, top y bottom. Estos 4 valores indican los píxeles que no modificará en esas direcciones. Veámoslo gráficamente para entenderlo mejor. Imaginemos que hemos cogido la siguiente textura:





Nuestros valores left, right, top y bottom indicarán los píxeles de la siguiente forma:



Los píxeles que no se encuentran en zona roja serán los que no se editen y el resto se expandirán según el tamaño que le indiquemos al dibujar la barra de la siguiente forma:




De esta forma NinePatch se encarga automáticamente de dibujarnos correctamente la barra. Ahora tan solo nos queda dibujarlo:


Con la línea anterior dibujamos el Ninepatch pasándole un batch que se encargará de dibujarlo (puedes ver el uso del SpriteBatch aquí), una posición inicial (x,y) que será la esquina inferior izquierda de nuestro NinePatch desde donde se comenzará a dibujar, y un ancho y alto (width y heigth).


Creando una barra


Para hacer nuestra barra necesitaremos dos NinePatch: uno para el fondo de la barra y otro para la barra que irá bajando o subiendo según perdamos o ganemos vida, stamina o lo que queramos.

Crear una barra es realmente fácil con los dos NinePatch, simplemente los creamos como hemos visto antes, les damos su textura y los colocamos donde queramos.

Para cambiar el tamaño de nuestro indicador, cada vez que cambie nuestra vida tendremos que modificar el ancho de nuestra barra, de modo que al volver a renderizarse, se verá como va variando la barra:






Notas:


  • Recuerda que deberás llamar al método dispose() de la textura que has creado. El resto de elementos que hemos visto en esta entrada no lo necesita.
  • Puedes usar una misma textura para los dos NinePatch, cambiando el área del textureRegion para que coja un trozo de la imagen u otro según te convenga.
  • Puedes crear una clase barra que extienda de Actor y así podrás dibujarla directamente en el Stage, o meterla dentro de una tabla como vimos aquí. De esta forma te será mucho más fácil recolocarla donde te interese.
  • Los NinePatch suelen usarse también para botones, menús... Úsalo donde mejor te venga!
  • Puedes ver más funciones de los NinePatch aquí.

6/3/14

[Tutorial] Skins, botones y tablas (libGDX)

Buenas gente! 

En esta entrada veremos como añadir botones a nuestra aplicación y como colocarlos donde queramos. Antes de ello veremos como cargar una “Skin” para darle un formato a nuestros botones.

Cargando un Skin


Una clase muy potente que nos aporta la librería scene2D es la clase Skin, que nos permite personalizar la apariencia de cualquier actor, cambiando su imagen y la letra del texto.

En este post veremos como cargar un Skin ya creado. Más adelante dedicaremos un post únicamente a la creación de un Skin ya que puede ser bastante extenso. Por ahora usaremos uno por defecto.

Un Skin se compone de varios ficheros. En nuestro caso tenemos dos para el tipo de letra (default.png y default.fnt), dos para definir el atlas con los recursos gráficos que representarán los actores (uiskin.png y uiskin.atlas), y un fichero Json para definir los estilos que le aplicaremos a cada uno (uiskin.json).

Todos estos ficheros deben estar, como siempre, en nuestra carpeta assets de nuestro proyecto name-android.

Una vez tenemos los ficheros, ya podemos crear nuestro Skin en el código con la línea:



A partir de aquí podemos tener una función getSkin() que devuelva este Skin para pasárselo a los actores que queramos.

Creación de un botón


Primero debemos declararlo. Nuestros botones serán de la clase TextButton:


Después lo inicializamos, para ellos hacemos un new:


Tras esto ya tendremos nuestro botón. Ahora deberemos añadirle un Listener para que al clickar sobre él realice la acción que queramos, como cambiar a una nueva pantalla, recuperar vida a un montruo, cualquier cosa:


Puedes ver más información y funciones de los botones aquí.

Con esto ya tendremos nuestro botón listo para ser usado. Ahora debemos de ponerlo en la función de dibujado. Para ello, como todo, tenemos muchas formas. La más directa sería hacerle un draw() indicando la posición exacta donde queremos que nos lo dibuje. Pero esto puede dar problemas con dispositivos de distinto tamaño, en redimensiones, etc. Un método muy cómodo es usar una Table.

Usando una Table


Para crear nuestra tabla ponemos el siguiente código donde queramos crearla:


Con estas líneas hemos creado una tabla usando la Skin que teníamos de antes. Con table.setFillParent( true ); le indicamos a la tabla que ocupe el mismo espacio que el padre (en nuestro caso, será el Stage) y, por último, añadimos la tabla a nuestro stage para que la dibuje.

Ahora vamos a añadir nuestros botones con la línea:


Ademas de simplemente añadir el botón, podemos indicarle el espacio que queramos que tenga a los lados de separación entre los otros actores de la tabla, el tamaño, etc. por ejemplo:


Aquí añadimos un botón llamado startGameButton con un tamaño del 40% del ancho de la pantalla y un 20% del alto. También le decimos que tenga una separación por debajo del 5% de alto y a la derecha del 10% de ancho. Podemos personalizarlo como queramos.

Puedes ver todas las funciones posibles aquí.

Cada vez que quieras añadir una nueva fila de botones (o actores) debes poner la línea:


Con esto ya tendríamos nuestros botones bien colocados en cualquier resolución de pantalla de una forma fácil y limpia.

Notas:

  • Los actores se meterán en orden en la tabla, en una misma fila hasta que crees otra.
  • Los actores no se sobrepondrán unos a otros en ninguna circunstancia. Si quieres poner algún actor sobre otro tendrás que hacer otra tabla, crearte una clase aparte con estos dos actores, o cualquier otra cosa.
  • Puedes crear celdas vacías en tu tabla para colocar a tu gusto los actores.
  • No es necesario hacer dispose() ni de la tabla ni de los botones de texto.

Referencias:


2/3/14

[Tutorial] Estructuración de pantallas y creación de estas (libGDX)

Buenas gente!

En esta entrada y una vez que tenemos una base mínima para comenzar a programar veremos que nos proporciona libGDX para facilitarnos la creación de las diferentes pantallas que tendrá nuestra aplicación.

Estructuración de pantallas:


Normalmente se suele tener una clase abstracta que contiene los valores y variables que por defecto tendrán todas nuestras pantallas y, luego, una clase por cada pantalla que queramos, extendiendo de la anterior.

Las aplicaciones suelen empezar con una pantalla “splash” donde, durante unos pocos segundos se muestra una imagen, bien de la empresa que lo creo o bien alguna imagen del juego, etc. Esta imagen se desvanece sola y da paso al típico menú inicial donde, mediante botones nos dirigimos a las distintas pantallas.


Creación de pantallas:


LibGDX ofrece una clase que nos facilita el trabajo con pantallas:


Se trata de una clase abstracta que implementa la interface ApplicationListener, que usamos en la clase principal de nuestra app, y además delega sus eventos en clases que implementan la interface Screen, lo que nos permite tener varias clases (que serán nuestras pantallas) y utilizar una u otra según nos venga mejor.

Tendremos una "pantalla base" que heredará de la clase Screen y de la cual heredarán el resto de pantallas y se encargará de realizar operaciones comunes a ellas, como inicializar algunos datos, o borrar toda la pantalla antes de empezar a dibujar las imágenes de cada pantalla.

Veamos ahora las funciones más importantes que deberá tener nuestra clase:

#### El constructor ####


En el constructor guardaremos en una variable el objeto de nuestra clase principal para poder acceder rápidamente a datos de ella.

Crearemos nuestra variable de tipo Stage con un tamaño de 0x0, valor que cambiará al hacer el resize().

Asignaremos a nuestro Stage los eventos de entrada de la aplicación (teclado, ratón, etc.)

#### Resize ####

Redimensionamos el tamaño de lo que nos muestra nuestro stage con la función setViewport, adaptándolo a las nuevas medidas


#### Render ####

Borramos todas las imágenes que hay en pantalla y le damos un color de fondo. Ya dentro del render de cada pantalla se dibujarán las imágenes de cada una (llamando antes a esta función de render con super.render())

#### DrawStage ####


Actualizará todos los actores de nuestro stage y los dibujará.

#### Dispose ####


Se ejecutará al terminar la aplicación. Debemos colocar aquí todas aquellas variables que java no borre por defecto, como las de tipo SpriteBatch, Texture, Stage, etc.


Visualización de pantallas:


En un primer lugar tenemos que indicarle a nuestro juego cual será la primera pantalla que se mostrará. Para ello colocamos el siguiente código en el constructor de nuestra clase principal:


Donde NameScreen será la clase de la pantalla que queramos visualizar en un primer lugar.

Podremos cambiar de pantalla con la siguiente línea de código:


Esta línea de código la podemos llamar al pulsar un botón, al pasar cierto tiempo, o al ocurrir ciertos hechos (como que mueras en un juego y tengas que volver a la pantalla de inicio, por ejemplo).

Una pantalla algo especial: Pantalla “Splash”:


La pantalla splash es aquella que se muestra al inicio de la aplicación durante unos segundos para luego desvanecerse y dar paso al menú principal.

El código de esta pantalla se encuentra prácticamente todo en su función show():

  • Inicialización de la imagen que vamos a mostrar:

  • Hacer la imagen transparente en un principio para hacerla aparecer después:

  • Añadir el efecto de aparición y desaparición de la imagen, con sus tiempos de retardo:

  • Y por último añadir la imagen a nuestro stage para que la muestre en la pantalla:

No olvides en la función dispose borrar la textura que hemos creado antes.


Notas:

  • Todo esto solo será necesario si tenemos más de una pantalla.
  • Si utilizas una clase AbstractScreen de la que heredan el resto de tus pantallas, coloca en ella todo el código y variables que se repiten en las pantallas, como el Stage, tu clase principal, etc.



Referencias: