Sei sulla pagina 1di 60

Programacin de videojuegos con

Introduccin a libGDX Descargar la librera Crear un proyecto JAVA nuevo Portar el proyecto JAVA a un proyecto Android Ciclo de vida de una aplicacin libGDX Grficos Texturas e Interpolacin TextureRegion TextuimagrePacker Empaquetar imgenes automaticamente Carga de imgenes empaquetadas Dibujar imgenes en pantalla Entrada Detectar pulsaciones en la pantalla tctil Audio Sounds Cargar sonidos Reproducir sonidos Descargar sonidos Music Cargar una msica Descargar una msica Navegando entre pantallas del juego Vibracin Cmaras Animacin Manual de buenas prcticas Separar la lgica de la presentacin Pginas para Desarrollo de Juegos Solucin de problemas

OBJETIVO
Este documento pretende ser una gua de uso del Framework LibGDX para el desarrollo de videojuegos multiplataforma. Para la redaccin del mismo se va a recopilar la informacin de diversas fuentes como puede ser la propia documentacin de la API del framework, foros, blogs y videoblogs. La idea es tener una documentacin bsica en castellano que est viva, es decir, que se vaya actualizando con el paso del tiempo e incluyendo las nuevas funcionalidades de las nuevas versiones.

INTRODUCCIN
En el mundo del desarrollo de aplicaciones actualmente existen multitud de Frameworks que ayudan al desarrollador a realizar sus proyectos minimizando el tiempo de desarrollo y simplificando tareas que, utilizando las herramientas usuales de cada plataforma, pueden llegar a ser complicadas o largas y tediosas. Entre estos Frameworks, tenemos algunos que son propietarios en el que es preciso pagar una licencia para la creacin de proyectos comerciales como pueden ser Corona SDK, Unity 3D, Gideros (aunque en este caso, hay una versin gratuita que se puede usar para proyectos comerciales con una intro mostrando el logo de Gideros), etc... Otros, por el contrario, siguen la filosofa del software libre y pueden ser usados para el desarrollo de software tanto comercial como privado sin el pago de licencia alguna como pueden ser Moai, Cocos 2D-X, libGDX... Como se puede observar hay una gran cantidad de opciones donde elegir. En mi caso, he decidido dar el paso por libGDX por varias razones: la comunidad es bastante activa, existe bastante documentacin, usa Java como lenguaje de programacin que es el nico que medio-domino, hace uso de herramientas contrastadas en el desarrollo de videojuegos como OpenGL, Open AL, Box-2D, etc... LibGDX es un framework multiplataforma de desarrollo de juegos para Windows, Linux y Android. Est escrito en Java con una mezcla de C/C++ para dar soporte y rendimiento a tareas relacionadas con el uso de la fsica y procesamiento de audio. LibGDX permite generar una aplicacin en su PC y utilizar el mismo cdigo en Android, de esta manera el proceso de pruebas y depuracin se realiza de forma ms rpida y cmoda ya que el PC es mucho ms rpido que el dispositivo Android. Con LibGDX nos aseguramos de que la misma aplicacin puede funcionar correctamente en diferentes dispositivos. LibGDX est compuesto por una serie de componentes que sern comunes a todas las aplicaciones: Marco de Aplicacin (application): manejar el bucle principal y adems estar encargado del clico de vida, es decir, los eventos de creacin,destruccin, pausa y resume de la misma. Componente de Grficos (graphics): nos permitir gestionar la representacin de imgenes y objetos grficos en la pantalla. Componente de Audio (audio): nos facilitar el acceso a los sonidos y msica de la aplicacin. Componente de entrada (input): para leer y escribir los diferentes ficheros de datos como por ejemplo, imgenes, archivos de configuracin, sonidos, msica, texturas,... Componente de Entrada/Salida (Files): gestionara la entrada a travs del teclado, pantalla tcil o acelermetro.

Los mdulos descritos anteriormente pueden ser accedidos va campos estticos de la clase Gdx. Esto, en esencia son un juego de variables globales que permiten el fcil acceso a cualquier mdulo de libgdx. Por ejemplo, para acceder al mdulo de audio, simplemente hay que escribir lo siguiente: // Crea un objeto de tipo AudioDevice en el que poder cargar fragmenos de audio de tipo PCM de 16 bits AudioDevice audioDevice = Gdx.audio.newAudioDevice(44100, false); Adicionalmente podramos ampliar la gama de mdulos con otros dos ms. Math: permite la gestin rpida de clculos matemticos orientados al desarrollo de videojuegos. Physics: que bsicamente es un wrapper de Box2D y permite controlar la gestin de colisiones.

Este grfico muestra en mayor detalle el sistema de mdulos de LibGDX

Realmente, estos mdulos son slo interfaces pblicas que ofrece la librera. La propia aplicacin ser la encargada de la gestin de los diferentes mdulos. Ventajas: Soporte 2d full (bajo y alto nivel) Mucha documentacin, tutoriales, ejemplos de cdigo Releases en forma peridica Se puede probar en escritorio (antes de subir a dispositivo mvil) Maneja Audio, eventos de entrada del usuario (Input), fsica,matemtica,archivos Soporta 3d aunque no es su fuerte. libGDX te da un acceso ms fcil a Bajo nivel Posibilidad de tomar un juego hecho en java jar 2d o 3d y adaptarlo a libgdx para q funcione nativo en android,eso hicieron con el juego Droid Invaders 3d. Desventaja: El soporte de alto nivel en 3d esta en construccin actualmente

Links de referencia: Pagina Oficial Wiki del proyecto Blog Foro Juego en 3d ya realizado: Droid Invaders Listado de Ejemplos Video Tutoriales Video Tutoriales en castellano Documentacin

Uso de la librera
Existen dos mtodos para el uso de la librera: el primero, ms manual, que consiste en descargar la misma e importarla en nuestro proyecto de forma manual y el segundo mtodo que es el ms rpido y el que yo recomiendo que es usando un GUI creado en Java que crea un proyecto con todo lo necesario de forma automtica para nicamente importarlo desde Eclipse.

Mtodo 1: Manualmente
Descargar la librera
Para descargar la librera debemos ir a la web de la misma: http://libgdx.badlogicgames.com/

Una vez en la web, pinchar en la opcin Download & Source. A continuacin seleccionamos la distribucin Nightly Builds que es la ltima versin que contiene las ltimas actualizaciones (y algunos bugs, tambin) pinchando en el botn Latest Nightly Build.

En la ltima ventana ya slo queda pinchar en la ltima versin que se llama libgdx-nightlylatest.zip

Crear un proyecto nuevo


Aunque se puede programar con cualquier IDE que permita programar en Java (como Netbeans, InteliJ IDEA, etc... ), la mayora de usuarios suele preferir usar Eclipse, por lo tanto es el IDE que se usar en este manual. Para crear un nuevo proyecto usando LibGDX, lo ms simple es usar una herramienta creada por Aurelien Ribbon llamada LibGDX Project Setup. Simplemente hay que descargarlo del blog de Aurelien Ribbon (http://www.aurelienribon.com/blog/). Una vez descargado, hay que descomprimir el fichero y nos encontraremos con un programa realizado en Java, por lo tanto simplemente hay que ejecutarlo haciendo doble click en el fichero .jar.

Para crear un proyecto JAVA en Eclipse simplemente en el men vamos a File > New > Java Project. Le damos un nombre al proyecto (en este caso Demo1). Elegimos la ruta donde se crear en memoria y le damos a Finish.

Una vez creado el proyecto el siguiente paso ser aadir la librera. Para ello una buena prctica es crear un directorio dentro del proyecto donde incluir las libreras que usemos. Para ello click derecho sobre nuestro proyecto y New > Folder. En nuestro ejemplo esta carpeta la llamaremos libs. Una vez creada esta carpeta, simplemente tendremos que aadir a la misma lo que necesitamos para este proyecto. Para aadir, nos vamos al directorio donde hemos guardado la librera descargada en el apartado anterior y podemos arrastrar o copiar los archivos que necesitamos (en la imagen). Nos quedara el proyecto de esta forma:

Ya tenemos las libreras en el directorio que hemos creado dentro del proyecto. Pero an no forman parte del mismo, el siguiente paso es aadirlas. Para ello seleccionamos los cuatro ficheros dentro de la carpeta libs, hacemos click derecho y en el men contextual seleccionamos Build Path > Add to Build Path . El proyecto queda de la siguiente forma:

Otra buena prctica, aunque no necesaria es aadir la informacin contenida en el Javadoc de la librera. El objetivo de esto es que cuando se muestre la ayuda emergente de eclipse veamos la informacin contenida en el Javadoc de la librera.

Para ello hacemos click derecho sobre el proyecto y en el men contextual Build Path > Configure Build Path... tras lo que se nos muestra lo siguiente:

En esta ventana desplegamos gdx.jar y tal como se ve en la imagen seleccionamos Javadoc location. Una vez hecho esto pulsamos sobre Edit...

Pulsamos en Browse... y buscamos la localizacin del Javadoc que se encuentra en libgdx-nightly > docs > api. Una vez seleccionado este directorio pulsamos sobre Ok para confirmar el cambio. Y ya tenemos esta caracterstica habilitada. Una vez preparado Eclipse y nuestro proyecto JAVA ya podemos empezar a trabajar.

Lo primero ser crear la clase principal del juego, que ser la encargada de manejar y controlar todo lo que ocurra en el juego. Para ello click derecho sobre src > New > Class.

Creamos la clase en el paquete com.desarrolladoresandroid.libgdx.demo1 El nombre de la misma es Demo1Game Esta nueva clase heredar de Game ( com.badlogic.gdx.Game).

Una vez creada la clase principal del proyecto, crearemos el punto de entrada para la ejecucin de la aplicacin JAVA. Una clase que nos permitir lanzar el juego.

Para ello creamos una clase que contenga el mtodo main:

Nombre de la clase: Demo1Desktop Mismo paquete que la clase principal Seleccionamos la opcin public static void main(String[] args)

Nos quedara el proyecto de la siguiente forma:

Para poder lanzar el juego aadimos en la clase Demo1Desktop tenemos que aadir lo siguiente: new LwjglApplication(new Demo1Game(), "Demo1", 320, 480, false); Los parmetros indican lo siguiente: new Demo1Game(). Instancia de la clase que implementa Game "Demo1". Que es el ttulo de la aplicacin. 320. Ancho en pxeles. 480. Alto en pxeles. false. Para indicar que no queremos utilizar OpenGL S 2.0 en este caso. Por lo que se utilizar el 1.1

Una vez hecho esto ya tenemos un juego que no hace nada y que podemos lanzar como aplicacin JAVA. Para lanzarlo tenemos que hacer click derecho en el proyecto y Run As > Java Application Una vez hecho esto nos saldr una ventana para seleccionar el punto de entrada de la aplicacin que en nuestro ejemplo es Demo1Desktop.java

El resultado de la ejecucin ser una pantalla negra con la resolucin indicada.

Portar el proyecto JAVA a un proyecto Android


Ahora crearemos el proyecto para compilarlo en Android. Para efectos practicos usare un ejemplo que yo ya tena. Hecho en escritorio llamado HolaLibgdx.

Crear carpeta libs dentro del proyecto y ponerle las siguientes libreras de las que descargamos incluyendo esas carpetas: Importante! "SE DEBEN INCLUIR LAS CARPETAS armeabi y armeabi-v7a como se ve en la imagen. Estas carpetas vienen en las libreras que descargamos"

Referenciamos las libreras copiadas. Click derecho al proyecto / build path / configure build path...

Antes de cerrar esa pantalla anterior ir a la pestaa project y adjuntarle la referencia al proyecto de escritorio.

Modificar la Activity principal "HolaLibGdxActivity" para que no extienda de Activity sino de AndroidApplication. (crt+shift+o) para resolver los imports necesarios.

package com.libgdx.holalibgdx; import android.os.Bundle; import com.badlogic.gdx.backends.android.AndroidApplication; import com.libgdx.holalibgx.HolaLibgdx; public class HolaLibGdxActivity extends AndroidApplication { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); //Aca inicializamos al app de escritorio. initialize(new HolaLibgdx(),false);

} }

Debera quedarnos as. 13. Lo ejecutamos en el emulador.

Desbloqueamos el dispositivo en el emulador.

y Se ejecuta exactamente lo mismo que en escritorio. Lo que hicimos recin, tambin compil la aplicacin en un archivo .apk dentro del directorio /bin del proyecto android, ese archivo .apk se lleva al dispositivo fisico real y al ejecutarlo te instala la app creada.

Mtodo 2: usando el libGDX Project Setup


Este segundo mtodo es mucho ms sencillo y seguro que nos quita dolores de cabeza innecesarios ya que simplemente ejecutando el GUI y rellenando unos pocos campos tendremos listo para importar a Eclipse no slo un proyecto para escritorio, sino que tambin lo podrs generar para android, IOS y HTML5 de forma simultnea. El nico requisito es que para crear cualquier proyecto, es necesario crear obligatoriamente el proyecto para Android. Lo que hace el asistente es crear un Core y un proyecto Android. Posteriormente el resto de proyectos hacen un soft-link a la carpeta Assests del proyecto Android, por lo que todos los recursos nicamente hay que almacenarlos en dicha carpeta del proyecto de Android para que estn disponibles en el resto de proyectos.

Descargar el libGDX Project Setup


Se descarga de la web de Aurelien Ribon pinchando aqu. Una vez descargado, simplemente se extrae del .zip el fichero .jar y se ejecuta. Aparecer la siguiente pantalla:

Como se puede observar, se pueden realizar dos acciones: crear un nuevo proyecto (pinchando en Create) o actualizar un proyecto existente (pinchando en Update). Si pinchamos en Create, la siguiente pantalla ser la siguiente:

En esta pantalla tenemos cuatro partes diferenciadas por un nmero que sirven para lo siguiente: 1. Configuration: en esta parte simplemente podremos poner el nombre del proyecto, el del paquete que lo va a contener, el de la clase del juego, el destino, as como las plataformas que queremos generar (como se puede comprobar, core y Android no se pueden deseleccionar porque son obligatorias). Si pinchamos en Show advanced settings> , nos dar la opcin de escribir los sufijos que queremos que tengan los diferentes proyectos. Tambin nos permitir configurar el SDK mnimo y el SDK objetivo de Android de nuestra aplicacin. 2. Library Selection: En esta parte est las diferentes libreras que queremos que tengan nuestros proyectos. Como mnimo es obligatorio que tenga LibGDX instalado (Obvio!). Para ello, si no la tenemos descargada, nos permitir descargarla pinchando en el icono de la derecha (nos descargar las latest nightlies version) o el penltimo de la derecha (nos descargar la ltima versin estable). Tambin podremos descargar e incluir libreras de terceros. 3. Overview: Esta parte simplemente nos mostrar el rbol de ficheros que va a generar el asistente para nuestra informacin 4. Generation: Esta parte nos informa de si podemos pasar al proceso de generacin o no y nos ofrecer un botn para ir a dicho proceso si todo est correcto.

Una vez pinchamos en el botn Open de generation screen, se nos mostrar la siguiente pantalla:

En esta pantalla, tenemos dos partes: La parte de la derecha es otra vez la pantalla Overview que nos muestra el rbol de ficheros a generar. La parte de la izquierda simplemente nos da la opcin Launch! que generar nuestro proyecto y la opcin Back por si queremos hacer algn cambio antes de la generacin.

Una vez se pincha en el botn de Launch! nuestro proyecto ser generado en la ruta que le indicamos en pasos previos. Finalmente se nos mostrar la siguiente pantalla con la informacin de cmo ha ido el proceso. Si no ha ocurrido ningn error, simplemente se cerrar para finalizar la ejecucin del asistente.

Una vez hecho esto, slamente queda importarlo desde Eclipse. Para ello, se abre Eclipse y se pincha en File -> Import, en la nueva ventana que aparece, seleccionar Existing Projects into Workspace y despus al botn Next.

En la ventana que aparece a continuacin, elegir la opcin Select root directory: y pinchar el botn Browse... para que nos permita seleccionar la carpeta en la que se han creado todos nuestros proyectos desde el asistente de libGDX. Una vez seleccionamos la carpeta, en el cuadro Projects: nos aparecern todos los proyectos que hay en el interior. Seleccionamos los que queramos importar (recordad que los proyectos core y Android son obligatorios), marcar la opcin Copy projects into Workspace para que nos copie los proyectos importados en nuestra carpeta de trabajo y a continuacin pinchamos en Finish.

Con esto, tendremos los proyectos importados y con todas las libreras necesarias para comenzar a trabajar con libGDX. El arbol de ficheros que se crea en Eclipse debe ser similar al siguiente:

Ciclo de vida de aplicacin libGDX


Este apartado describe cmo se estructura una aplicacin libgdx.

una

LA APLICACION
Es el principal punto de entrada para cualquier aplicacin libgdx. La interface Application determina la plataforma y los graficos de fondo que sern utilizados por la aplicacin. La interface tambin proporciona los mtodos para acceder a grficos, audio, archivos de entrada y mdulos de E/S. Tambin da acceso a un mdulo de Logging el cual funciona en todas las plataformas.

Las clases de inicio


El nico cdigo de plataforma especfica que es necesario escribir, son las llamadas clases de inicio. Por cada plataforma, un pequeo trozo de cdigo instanciar una implementacin concreta de la interface Application. Para una aplicacin de escritorio, por ejemplo, usando el backend Lwjgl quedara algo as: public class DesktopStarter { public static void main(String[] argv) { LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); new LwjglApplication(new MyGame(), config); } } Para Android, la clase de inicio correspondiente quedara as: public class AndroidStarter extends AndroidApplication { public void onCreate(Bundle bundle) { super.onCreate(bundle); AndroidApplicationConfiguration config = new AndroidApplicationConfiguration(); initialize(new MyGame(), config); } } Estas dos clases viven en proyectos separados. El cdigo actual de la aplicacin est localizado en una clase que implementa el interface ApplicationListener (MyGame en el ejemplo anterior). Una instancia de esta clase es pasada a los mtodos de inicializacin respectivos de cada implementacin de Application de cada backend. La aplicacin

llamar entonces a los mtodos de ApplicationListener en el momento adecuado tal como se comenta en el punto Ciclo de vida de una aplicacin ms adelante. LibGDX es compatible actualmente con dos back-ends de aplicaciones de escritorio (lwjgl y JOGL), otra para Android, otra para HTML5 y otra para IOS. Para crear una aplicacin libGDX, se ha de implementar la interfaz ApplicationListener primero.

APPLICATION LISTENER
ApplicationListener es el responsable de la inicializacin de la aplicacin, la actualizacin del estado del juego (es decir, la lgica del juego), renderizacin de la imagen, pausado del juego, guardar el estado y la liberacin de los recursos al salir de la aplicacin. Es tambin el lugar donde los eventos del ciclo de vida son manejados. Cada aplicacin / juego, sin importar el back-end y / o plataforma de destino tendr que implementar la interfaz ApplicationListener. La implementacin es exactamente la misma para todas las plataformas. Por tanto, Application es responsable del circuito de juego y ApplicationListener es el lugar donde se implementa la lgica del juego. La implementacin de la interfaz ApplicationListener

Las aplicaciones que usan libGDX, escucharn 6 notificaciones principales: CREATE, RESIZE, RENDER, PAUSE, RESUME y DISPOSE.

create (): Se llama una vez cuando se crea la aplicacin.

resize(int width, int height): Se llama a este mtodo cada vez que la pantalla del juego cambia su tamao y el juego no est en el estado de pausa. Tambin se le llama slo una vez justo despus del mtodo create (). Los parmetros son la nueva anchura y altura de la pantalla. render (): Mtodo llamado por el bucle del juego de la aplicacin cada vez que se renderiza. La actualizacin del juego tambin tiene lugar aqu antes de la representacin real. pause (): El mtodo de pausa se llama justo antes que se destruya la aplicacin. En Android se llama cuando el botn de inicio se presiona o haya una llamada entrante. En el escritorio se llama justo antes de dispose () al salir de la aplicacin. Es un buen lugar para guardar el estado del juego en Android, ya que no se garantiza que sea reanudado. resume(): Este mtodo es llamado slo en Android, cuando la aplicacin recibe el foco. En el escritorio este mtodo no ser llamado nunca. dispose (): Se le llama cuando la aplicacin se destruye. Es precedido por una pausa ().

Ciclo de vida de una aplicacin


Los mtodos antes mencionados son provocados por la aplicacin durante su ciclo de vida. El siguiente diagrama muestra las diferentes fases por las que pasa una aplicacin libGDX:

Mdulos de libGDX
El ncleo de libGDX se basa en cinco interfaces que proveen formas de interactuar con el SO. Cada backend implementa estos interfaces. Estos son: Aplicacin (Application) Grficos (Graphics) Entrada/Salida (Files) Entrada (Input) Audio (Audio)

Acceso a los mdulos


El acceso a los mdulos anteriormente listados puede hacerse a travs de campos estticos de la clase Gdx. Esencialmente es un juego de variables globales que permiten el fcil acceso a cualquier mdulo de libGDX. Por ejemplo, para acceder al mdulo de audio simplemente se puede escribir lo siguiente:
// creates a new AudioDevice to which 16-bit PCM samples can be written AudioDevice audioDevice = Gdx.audio.newAudioDevice(44100, false); Gdx.audio es una referencia a la implementacin backend que ha sido instanciada en el inicio de la instancia Application.

Grficos
El mdulo de grficos es un resumen de la comunicacin con el GPU y proporciona mtodos de conveniencia para obtener las instancias de OpenGL ES. Se encarga de todo el cdigo repetitivo necesarios para hacerse con el ejemplo de OpenGL y se ocupa de todas las implementaciones proporcionadas por el fabricante. Dependiendo del hardware subyacente, los contenedores pueden ser o pueden no estar disponible. El mdulo de grficos tambin proporciona mtodos para generar mapas de pixels y texturas. En el siguiente cdigo podemos ver cmo obtener una instancia de la API OpenGL 1.0: GL10 gl = Gdx.graphics.getGL10 (); El mtodo devuelve una instancia que puede ser usada para dibujar en la pantalla. En el caso que la configuracin de hardware no sea compatible con OpenGL ES 1.0, devuelve null.

Consideraciones previas sobre OpenGL


Previamente a dibujar nada con libGDX, lo primero es crear una cmara ortogrfica. Esto es debido al funcionamiento de OpenGL. Lo nico que hay que tener en cuenta es que al crear una cmara ortogrfica tienes que tratar el eje z a 90 grados como si estuvieras mirando un cuadro para poder ver en 2D. Para crear una cmara ortogrfica: public class Game implements ApplicationListener { public OrthographicCamera camera; public void create(){ camera = new OrthographicCamera(640, 480); }

Otra cosa a tener en cuenta antes de renderizar imgenes en libGDX, es realizar un borrado de pantalla en el mtodo render incluyendo las siguientes sentencias al principio: gl.glClearColor(0.1f, 0.0f, 0.0f, 1); //configura un color y un alpha al //borrado gl.glClear(GL10.GL_COLOR_BUFFER_BIT); //realiza el borrado con una mscara

Texturas e Interpolacin
Texture es una "imagen" en la memoria del chip grfico (las imgenes en disco se cargarn en esta zona de memoria). En OpenGL v1.1 el ancho y alto de una textura tiene que ser potencia de 2 (...32, 64, 128, 256, 512, 1024, etc). Aunque en los ejemplos se definen la textura cuadrada, no tiene por qu ser as. Puedes tener una textura de 128x32, 32x256, etc. . Si usamos OpenGL v2, no se tiene esta limitacin. Por ejemplo, el HTC G1 soporta como mucho, una textura de 1024x1024 (Aunque puedes tener ms de una textura a la vez). Intentar utilizar texturas ms grandes en este dispositivo provocarn errores en el juego.La recomendacin es que no pases del valor 1024 para establecer el ancho o alto de tus texturas. Un parmetro muy importante que hay que indicar a la hora de crear un objeto Texture es un valor TextureOptions que indicar qu mtodo se utilizar para redimensionar las imgenes que tenemos dentro de la textura. (Para no complicar las cosas, dejaremos esa explicacin).

Se pueden elegir los siguientes modos: NEAREST: La imagen aparecer pixelada. Es mucho ms rpido, pero la imagen tiene menor calidad.

Original:

Ampliada con NEAREST:

BILINEAR: La imagen aparece ms difuminada. Es un poco ms lento, pero no vers pxeles en la misma.

Original: Ampliada con BILINEAR:

REPEATING: Si la textura es de 32x32 y tiene que dibujarse sobre una superficie de 64x64, veremos 4 imgenes rellenando ese hueco. Como si pusiramos la misma imagen una y otra vez repitindola. Este modo no funciona con los Sprites normales, as que por ahora, vamos a ignorarlo.

Cuando utilizas imgenes que contienen valores alpha (transparencia) puedes encontrarte con que te aparezcan "halos" que rodean los bordes de las mismas. Aqu es donde entra en juego la tcnica " premultiplied alpha", la cual corrige ese problema. Intenta evitar utilizar "premultiplied alpha" a menos que veas cosas raras en los bordes de tus imgenes, como sobras o halos resplandecientes que no deberan estar. Si quieres una interpolacin bilineal, estableces: TextureOptions.BILINEAR

Si quieres una interpolacin bilineal con " premultiplied alpha", estableces:


TextureOptions.BILINEAR_PREMULTIPLYALPHA Lo mismo ocurre si quieres interpolacin NEAREST con o sin "premultiplied alpha". Es cosa tuya explorar los valores que puedes elegir de TextureOptions. Para finalizar, decir que: TextureOptions.DEFAULT = TextureOptions.NEAREST_PREMULTIPLYALPHA

TextureRegion
Define un rea rectangular de una textura. El sistema de coordenadas utilizado tiene su origen en la esquina superior izquierda con el eje x apuntando hacia la derecha y el eje y apuntando hacia abajo. Las textureRegion son empleadas para crear nuevas imagenes( o tambin llamados actores de tipo imagen) asociadas a un rea de una textura. Tiene varias opciones para construir un objeto de esta clase, son los siguientes:
TextureRegion()

Construye una region sin textuta ni coordenadas definidas.Se podran definir despues empleando los mtodos de la clase.
TextureRegion(Texture texture)

Construye una region de tamao especificado en la textura.


TextureRegion(Texture texture, float u, float v, float u2, float v2)

TextureRegion(Texture texture, int width, int height)

Construye una regin con con las coordenadas de la textura y el ancho y alto especificado.
TextureRegion(Texture texture, int x, int y, int width, int height)

Define una tetura especificando el punto (x,y) de origen y el tamao del area (ancho,alto)

TextureRegion(TextureRegion region)

Construye una regin con la misma textura y coordenadas que la regin pasada como parmetro.
TextureRegion(TextureRegion region, int x, int y, int width, int height)

Construye una regin con la misma textura y coordenadas que la regin pasada como parmetro. Un ejemplo de seleccin de un rea con TextureRegion es el siguiente:

TextureRegion texture = new TextureRegion(new Texture(

Gdx.files.internal("data/jugador.png")), 0, 0, 40, 40);

TexturePacker
Empaqueta imagenes en un Texture Atlas. Lo ideal es almacenar muchas imgenes ms pequeas en una imagen ms grande,obligar a la textura ms una vez, luego dibujar porciones de la misma muchas veces. libgdx tiene una clase TexturePacker que es una aplicacin de lnea de comandos queempaqueta muchas imgenes ms pequeas en 1imgen ms grande. TexturePacker se basa en este algoritmo. Tambin tiene una fuerza bruta, el embalaje de varias maneras y luego elegir el resultado ms eficiente.

Empaquetar imgenes automaticamente


Se deber importar la libreria: gdx-tools.jar El cdigo para ejecutar el TexturePacker:

Settings settings = new Settings(); settings.padding=2; settings.maxHeight=1024; settings.maxWidth=1024; settings.incremental=true; TexturePacker.process(settings, "images", "data");

Se deber tener en el proyecto una carpeta images, con las imagenes a procesar. El proceso generar la carpeta data con el pack realizado.

Carga de imgenes empaquetadas


Asi se recuperan las texturas de un textureAtlas Generado por un packer.

public static AtlasRegion background; atlas = new TextureAtlas(Gdx.files.internal("data/pack")); background = atlas.findRegion("background");

Dibujar imgenes en pantalla


Creamos la clase Asset para almacenar los recursos de imagenes. public class Assets { /** Contiene el paquete de texturas. */ public static TextureAtlas atlas; /** Regiones dentro de la public static AtlasRegion public static AtlasRegion public static AtlasRegion public static AtlasRegion public static AtlasRegion imagen de textura empaquetada */ background; soundoff; soundon; start; title;

/** * Load. */ public static void load(){ atlas = new TextureAtlas(Gdx.files.internal("data/pack")); background = atlas.findRegion("background"); soundoff = atlas.findRegion("soundoff"); soundon = atlas.findRegion("soundon"); start = atlas.findRegion("start"); title = atlas.findRegion("title");

public static void dispose(){ atlas.dispose(); }

public class HolaLibgdxExample implements ApplicationListener { /** The gui cam. */ OrthographicCamera guiCam; /** Se utiliza para dibujar y optimizar las imagenes en el renderizado de la pantalla. */

SpriteBatch batcher; @Override public void create() { } @Override public void dispose() { batcher.dispose(); } @Override public void pause() { } @Override public void render() { GL10 gl = Gdx.graphics.getGL10(); //referencia a OpenGL 1.0 gl.glClearColor(0,1,0,1); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); guiCam = new OrthographicCamera(10, 15); //definicion de nuestra propia medida del juego guiCam.position.set(10f / 2, 15f / 2, 0); // Donde estara mirando la camara batcher = new SpriteBatch(); //crear solamente un batcher por pantalla y eliminarlo cuando no se use guiCam.update(); batcher.setProjectionMatrix(guiCam.combined); //Dibujando el Background batcher.disableBlending(); //Se elimina graficamente la transparencia ya que es un fondo batcher.begin(); batcher.draw(Assets.background, 0, 0, 10, 15); batcher.end(); //Dibujando elementos en pantalla activamos el Blending batcher.enableBlending(); batcher.begin(); batcher.draw(Assets.title, 1, 8, 8, 6); batcher.draw(Assets.start, 2, 5, 6, 1); batcher.draw(Assets.soundon, 2, 3, 6, 1); batcher.end(); } @Override

public void resize(int arg0, int arg1) { } @Override public void resume() { } }

Entrada
El mdulo de entrada permite capturar los diversas formas de entrada de cada plataforma. Permite saber del estado de cada tecla, la pantalla tctil y el acelermetro. En el escritorio la pantalla tctil se sustituye por el ratn, mientras que el acelermetro no est disponible. En el fragmento de cdigo siguiente se obtiene el touch actual de coordenadas si hay un touch del celular (o del ratn en el escritorio): if (Gdx.input.isTouched ()) { System.out.println ("de entrada se produjo en x =" + x + ", y =" + y); } De manera similar a todos los medios de entrada pueden ser consultados y manipulados.

Detectar pulsaciones en la pantalla tctil


Se debe difinir un Vector, un area ficticia donde se captar el evento de pulsacin del dedo. Usamos tambien el objeto de OrthographicCamera, para convertir los pixeles en nuestra medida en metros. Luego preguntamos si el boton que creamos BoundingBox tiene un touch. Y escribimos el cdigo para manejar ese evento

Audio
LibGDX cuenta con un mdulo de audio que ofrece dos tipos de recursos: El sonido y la msica. Ambos tipos soportan el formato WAV,MP3 y OGG. Tambin ofrece acceso al hardware de sonido. La diferencia entre el sonido y la msica es que el sonido se almacena en memoria y se usa cada vez que se quiere reproducir alguno de ellos, mientras que la msica son streams de sonido que estn almacenados en ficheros y a los que se accede cada vez que se quiere reproducir algo. El siguiente fragmento de cdigo reproduce un fichero de msica desde el disco con el volumen a la mitad: Music music = Gdx.audio.newMusic(Gdx.files.getFileHandle("data/myMusicFile.mp3", FileType.Internal)); music.setVolume(0.5f); music.play(); music.setLooping(true);

Sonidos
Sound es una clase destinada a la reproduccin de un efecto de sonido. Lo normal es cargar el sonido desde un

archivo a memoria y luego reproducirlo a travs del mtodo Sound.play(). Los sonidos son generalmente cortos, llegando a durar unos pocos segundos ya que al ser cargados en memoria pueden llegar a ocupar demasiado, incidiendo directamente en el rendimiento. Cuando ya no vayamos a usar ms ese sonido ser necesario llamar al mtodo Sound.dispose() para liberar memoria en el dispositivo.

Cargar sonidos
Los Archivos para los efectos de sonido los pondremos dentro de una carpeta llamada data Para cargar en memoria un efecto de sonido tan slo ser necesario definirlo como tipo Sound y llamar al mtodo Gdx.audio.newSound pasando como parmetro el fichero dentro del directorio data. El siguiente fragmento de cdigo carga un sonido en memoria. Sound explosion explosion = Gdx.audio.newSound(Gdx.files.internal("data/explosion.ogg")); Puesto que el sonido ser una cosa que slo se cargar una vez durante toda la vida de la aplicacin, haremos la llamada a newSound en nuestro mtodo destinado a la carga de datos.

Reproducir sonidos
Para reproducir un sonido previamente cargado en memoria tan slo ser necesario hacer una llamada al mtodo play del sonido pasando como parmetro un valor entre 0 y 1 que representar el volumen. explosion.play(1);

Descargar sonidos
Una vez que no queramos hacer uso del sonido ser necesario descargarlo de memoria ya que en los dispositivos mviles, la memoria RAM sigue siendo un elemento muy precidado. Para descargar de memoria un sonido tan slo ser necesario llamar al mtodo dispose del objeto. Esto podemos hacerlo en nuestro apartado destinado a la descarga de datos o bien en el mtodo dispose de la aplicacin, como ya hemos visto en el apartado de ciclo de vida de la aplicacin. explosion.dispose();

Musica
Music es la clase de libgdx para cargar archivos de sonido en nuestros juegos deriva de la clase Disposable consta de los siguientes mtodos: play() Comienza a la cancin,en el el caso de estar pausada la reanuda donde se quedo y en el

caso de que se hubiera parado la comienza desde el principio. pause() Pausa la cancin, si la cancin no ha empezado aun o esta ya ha finalizado, este mtodo es ignorado al llamarlo. stop() Para la cancin.La siguiente vez que se llame al mtodo play() la cancin comenzar desde el principio. isPlaying() Funcin que devuelve un booleano, indicando si es verdad o no que la cancin esta sonando. setLopping() Admite como parmetro un booleano para indicar si se activa la funcin loop en la cancin, esta funcin activa la repeticin indefinida de la msica, de tal forma que si se llama al procedimiento indicando true, la cancin se repite indefinidamente hasta que la paremos o hasta que desactivemos el loop. isLopping() Funcin que devuelve un booleano, indicando si es verdad o no que la cancin esta sonando. setVolume() Vara el volumen del sonido, admite por parmetros (0 1) ,con un 0 se pone en silencio y con 1 se pone el volumen al mximo. getPosition() Funcin que devuelve un float con la posicin de la cancin en milisegundos dispose() Es el destructor de la clase. Es muy conveniente llamarlo cuando no sea necesaria la musica ya que consume memoria del disposivoLibgdx soporta los formatos MP3, OGG y WAV. Es conveniente usar Ogg en casi todos los casos. Si necesita ms control sobre el dispositivo de audio, puede utilizar el AudioDevice y clases Audiorecorder que tambin se obtiene de la interfaz de audio. Estas clases permiten a la salida de las muestras de PCM para el dispositivo fsico de audio, as como muestras PCM registro de un micrfono conectado.

Cargar una msica


Las msicas se pueden almacenar de forma interna en el proyecto que estamos desarrollando o en una ruta fija(por ejemplo para poner como msica un sonido standard del sistema) Para cargar una msica en memoria debemos instanciar un objeto de la clase Music pasandole como parmetro un puntero al fichero del tipo FileHandle nativo de java, de la siguiente forma: Music music = Gdx.audio.newMusic(Gdx.files.getFileHandle("data/8.12.mp3", FileType.Internal)); En este ejemplo la cancin 8.12.mp3 esta guardada dentro de la carpeta del proyecto data, por lo que el tipo de archivo le indicamos que es interno. FileType.Internal. En el caso de no poder abrir el archivo se genera una excepcin GdxRuntimeException Los tipos posibles de ficheros son los nativos de Javade tipo File.FileType, estos son: External Path relativo a la raiz del almacenamiento SD de android. Internal Path relativo a la ruta de la aplicacion android o dicho de otro modo relativo al directorio raiz de la aplicacin creada. Classpath El path del fichero esta en una ruta relativa a la raiz del Clashpath Absolute El path esta indicado de forma absoluta, indicando el filesystem que lo contiene.

Reproducir una msica


Para reproducir una msica como hemos mencionado antes basta con llamar al metodo play() desde el objeto instanciado de tipo Music. Vamos a verlo mas claramente con un pequeo ejemplo de como dejar una msica reproducindose en un bucle infinito donde la msica es un archivo mp3 almacenado en una carpeta que hemos llamado data Music music = Gdx.audio.newMusic(Gdx.files.getFileHandle("data/8.12.mp3", FileType.Internal)); music.setLooping(true); music.play();

Descargar una msica


Una vez que no queramos hacer uso del sonido ser necesario descargarlo de memoria. Para descargar de memoria un sonido tan slo ser necesario llamar al mtodo dispose del objeto. Esto podemos hacerlo en nuestro apartado destinado a la descarga de datos o bien en el mtodo dispose de la aplicacin, como ya hemos visto en el apartado de ciclo de vida de la aplicacin. En el caso de que la msica estuviera en un bucle lo lgico es pararla antes de eliminarla por seguir una secuencia lgica, y en parte por esttica de la programacin, estos se hace llamando al mtodo stop, por tanto el orden seria : music.stop(); music.dispose();

Navegando entre pantallas del juego


Game extiende de AplicationListener para implementar multiples pantallas. Una Screen es una pantalla de un juego. Opciones, Menu principal, nivel 1, nivel 2, creditos, etc. Para cambiar entre pantallas haremos: Screen gameScreen = new GameScreen(game); game.setScreen(gameScreen); return; es decir, creamos la screen, y se la seteamos a la instancia del juego.

Vibracin
Para agregarle al juego del arkanoid (el del video tutorial) que vibre al chocar la barrita con la pared izquierda por modificamos el mtodo render() de la clase GameScreen. try { Gdx.input.vibrate(200); System.out.println("vibra"); } catch (Exception e) { System.out.println(e); }

Cmaras
OrthographicCamera guiCam; guiCam = new OrthographicCamera(10, 15); //definicion de nuestra propia medida del juego

10x15 metros: Esto es porque dividmos los 320x480 pixeles en bloques de 32px.
guiCam.position.set(10f / 2, 15f / 2, 0); // Donde estara mirando la camara

Animacin
Crearemos un personaje de un personaje y haremos una animacin, es decir, que camine como si se estuviera moviendo. Aqu se ve el ejemplo de un hombre corriendo. La imagen se puede ver como una matriz de imgenes las cuales se van a recorrer con dos ciclos y se van a pasar por imagen a un vector. Cuando se crea la animation, se le pasa por parametro la velocidad con la que se mueve el frame y el vector de imgenes. Por ltimo cuando se invoca al spriteBatch.draw(); se le indica el vector que contiene las imgenes, la posicin de X y de Y en donde se quieren dibujar las mismas.

Usaremos la siguiente Imagen como secuencia:

Copiaremos esta imagen, en la carpeta /imagen del proyecto

Creamos una clase que implemente screen animacin:

public class AnimationScreen implements Screen { Game game; static final float WORLD_WIDTH = 5; static final float WORLD_HEIGHT = 3.3f; private static final int FRAME_COLS = 6; // #1 private static final int FRAME_ROWS = 5; // #2 OrthographicCamera guiCam; SpriteBatch batcher; Animation walkAnimation; // Texture walkSheet; // #4 TextureRegion[] walkFrames; SpriteBatch spriteBatch; // TextureRegion currentFrame; float positionX=1; float stateTime; // #8 #3 // #5 #6 // #7

Inicializamos en el constructor lo referente a la animacin: public AnimationScreen(Game game) { this.game = game; batcher = new SpriteBatch(); guiCam = new OrthographicCamera(WORLD_WIDTH, WORLD_HEIGHT); guiCam.position.set(WORLD_WIDTH / 2, WORLD_HEIGHT / 2, 0); walkSheet = new Texture(Gdx.files.internal("images/man.png")); // #9 TextureRegion[][] tmp = TextureRegion.split(walkSheet, walkSheet.getWidth() / FRAME_COLS, walkSheet.getHeight() / FRAME_ROWS); // #10 walkFrames = new TextureRegion[FRAME_COLS * FRAME_ROWS]; int index = 0; for (int i = 0; i < FRAME_ROWS; i++) { for (int j = 0; j < FRAME_COLS; j++) { walkFrames[index++] = tmp[i][j]; } } walkAnimation = new Animation(0.025f, walkFrames); // #11 spriteBatch = new SpriteBatch(); // #12 stateTime = 0f; // #13 } Ahora en el render hacemos: Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // #14

stateTime += Gdx.graphics.getDeltaTime(); // #15 currentFrame = walkAnimation.getKeyFrame(stateTime, true); // #16 spriteBatch.begin(); spriteBatch.draw(currentFrame, positionX, 2); // #17 spriteBatch.end(); update(delta);

#16: obtenemos el frame correspondiente en base al tiempo que lleva moviendose Metodo Update public void update(float delta){ positionX+=0.1f; }

Si necesitan el cdigo fuente completo de este ejemplo: javi10823@gmail.com

Manual de buenas prcticas


TO DO: Introduccin a cosas para ser ms eficientes y limpios escribiendo cdigo. Para ser limpios y eficientes escribiendo cdigo es importante tener en cuenta varias cosas como creaciones de mtodos para simplificar el cdigo, no hacer condiciones muy largas o muchos bucles anidados, estos son solo algunos ejemplos, ahora explicare un poco mas extenso algunos de los puntos mencionados anteriormente. - Definir variables al principio de la clase/mtodo, de esta forma se tiene un acceso rpido a esa variable y sabemos de un simple vistazo que atributos tiene. - Respetar las reglas de nomenclatura de los lenguajes tales como los siguientes: - Los nombres de las variables comienzan con letras minsculas, y en caso de contener varias palabras se le pondr mayscula a la primera letra de cada palabra a partir de la segunda palabra. - Los nombres de los mtodos se escribirn en minscula siguiendo la misma regla que el nombrado de las variables. Por lo general, el nombre de estos suelen ser verbos. - Las variables finales se escribirn integramente en mayscula, separando, si fuera necesario, diferentes palabras por medio del carcter guin bajo _ - El nombre de los paquetes se realizar integramente en minscula, aunque contenga varias palabras. - El nombre de las clases comenzar con la primera letra en mayscula y las siguientes en minscula. En caso de contener varias palabras se las distingir poniendo mayscula la primera letra de cada palabra. - Tabular el cdigo para una mayor compresin del mismo. En java, a diferencia de otros lenguajes de programacin como puede ser python, no es necesario que las lineas de cdigo estn tabuladas para pertenecer a un mtodo/funcin/clase ya que para esto se utilizan las llaves, pero de esta forma se hace el cdigo ms legible. - Realizar un estudio que relacione el tiempo de procesamiento vs almacenamiento. En ocasiones

una lista puede estar muy bien para almacenar datos, pero un array tiene un acceso inmediato al dato contenido. - Si ves que programando escribes varias veces lo mismo, creaciones de objeto que varan muy poco, comprobacin de un objeto, cambiar un objeto, lo mas probable es que puedas cambiarlo por una funcin o un mtodo. Por ejemplo: - Crear un casillero de 10 x 10, esto implica dibujar o crear 100 casillas, escribiras 100 veces: batcher.draw(casilla, posX, posY, 1, 1); Y esto no es eficiente, pero podras dibujarlo con: for (int i = 1; i < 11 ; i++) { for (int j = 1; j < 11; j++) { batcher.draw(casilla, i, j, 1, 1); } } } - Usar switch case si ves que comparas lo mismo dentro de muchos if, teniendo en cuenta que un case solo comprueba integer y enumerados. - Antes de crear un mtodo comprobar que no existe ya, o parecido, para que puedas modificarlo, siempre que al modificarlo no haya nada dependiendo de el. - Usar varios for anidados hace que el programa se ralentice mucho, ya que podemos encontrarnos con recorridos con muchos elementos y los recorre todos por lo que ralentiza mucho y no es eficiente, esto no suele aparecer mucho pero hay que tener cuidado a la hora de meter for while o do, uno dentro de otros ya que puede dar problemas Otra de las cosas que hay que tener en cuenta a la hora de programar es ser limpio y no escribir como se nos van ocurriendo las cosas y dejarlo as, ya que si despus alguien quiere usar nuestro o cdigo o simplemente saber como funciona le sera imposible, por eso cuando estemos programando hay que intentar dejar lineas simples, o explicar con comentarios cuando veamos que algo puede que no se entienda. Lo que tambin ayudara a la hora de la limpieza y de la claridad seran la clases, lo mas importante en el caso de la programacin orientada a objetos. Siempre que vallas a utilizar un objeto que vaya a tener mas de una propiedad se utilizan clases. Algunos ejemplos: - Pelota en un espacio: Adems de su nombre tendr un x e y indicando su posicin. - Personaje: Adems de su nombre puede tener su posicin indicada con x e y, un inventario guardado en un array, o cualquier cosa. En estos y en muchos mas la creacin de una clase es lo mejor, cuando veas que estas creando dos variables para guardar informacin sobre un objeto dentro de una clase seguramente podrs

instanciar ese objeto desde otra clase y sera mas claro que poniendo tantos atributos.

Separar la lgica de la presentacin


Con lgica nos referimos a todas las comprobaciones, modificaciones o creaciones que se hacen antes de renderizar, ya que el proceso de renderizado solo ya es lento si metes tambin toda la logica ara que el juego sea lento, por esto es recomendable hacerlo en una clase aparte. Para hacer la parte lgica basta con crear un clase aparte del renderizado donde comprobemos lo que haga falta antes de pintar en pantalla. Por ejemplo: -Cambiar la velocidad de una pelota al chocar con una pared: // Choque en pared izquierda if(ball.position.x - 0.25 < 1){ ball.position.x = 1 + 0.25f; ball.direction.x = ball.VELOCITY; } -Comprobar el valor de una casilla para pintarla de un color diferente: public AtlasRegion casilla(int x, int y){ switch(matriz[x][y]){ case 0: return Assets.casillaG; break; case 1: return Assets.casillaB; break; case 2: return Assets.casillaR; break; case 3: return Assets.barco; break; default: return Assets.barco2; break; } } -Actualizar valores de las variables. En resumen todo lo que no sea dibujar en pantalla y deba ejecutarse siempre se ha de poner fuera del renderizado, pero teniendo en cuenta que el render lo debe llamar, si hicieramos la parte logica en una clase llamada World deberia quedar algo parecido a esto: public class World {

//atributos internos //constructor public World(){ initialize();//metodo interno, abajo creado. } //inicializar variables o limpiar public void initialize(){ } //actualizacion public void update(){ //aqui deber ir todo lo que forma parte de la lgica para el renderizado de la pantalla, teniendo en cuenta que hay que llamarlo desde el render, que se el puede pasar los parmetros que se necesiten } } Puede haber distintos World, y puede usarse en las pantallas que se necesiten, no tiene porque ser solo de una. Para usar el World hay que llamarlo desde el render, pero antes tiene que haber un objeto desde el que llamarlo, que sera creado en la clase de la pantalla, aqui un ejemplo: public class GameScreen implements Screen{ World world; //Atributos public GameScreen(){ this.world = new World();//esto llama al contructor, que a la vez llama al inizialite. //inicializacion de atributos.

} @Override public void dispose() { } @Override public void hide() { } @Override public void pause() { } @Override public void render(float delta) {//delta es el tiempo transcurrido desde la ultima llamada por si la logica lo necesita. World.update();//aqui actualizamos la logica del juego. //Pintar imgenes. } @Override public void resize(int width, int height) { } @Override public void resume() { } @Override public void show() { } }

Recursos para Desarrollo de Juegos


Descargar Sonidos http://www.mysoundfx.com/ Musica para dar ambiente a tu juego http://pro.jamendo.com/es/ Tutorial creacin Sprites Animadas desde cero http://ilovepixel.net/tutorial.html 2d Game Art For Programmers http://2dgameartforprogrammers.blogspot.com/ Crear un personaje para Animacin http://2dgameartforprogrammers.blogspot.com/2011/10/creating-game-character.html Caras http://2dgameartforprogrammers.blogspot.com/2011/11/creating-basic-face.html Fondos http://2dgameartforprogrammers.blogspot.com/2011/10/more-fun-with-gradients.html

Potrebbero piacerti anche