Vous êtes sur la page 1sur 50

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

Introduccin a libGDX

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 de sern comunes a todas las aplicaciones. Marco de Aplicacin, que 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. Un componente de Grficos que nos permitir gestionar la representacin de imgenes y objetos grficos en la pantalla. Un componente de Audio, que nos facilitar el acceso a los sonidos y msica de la aplicacin. Un componente de de Entrada y Salida para leer y escribir los diferentes ficheros de datos como por ejemplo, imgenes, archivos de configuracin, sonidos, msica, texturas,... Un componente de Entrada que gestionara la entrada a travs del teclado, pantalla tcil o acelermetro.

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 la ultima fue en setiembre y anterior en Mayo Se puede probar en desktop (antes de subir a mobile) Maneja Audio, input (usuario), fsica,matemtica,archivos Mas poderoso que Andengine Soporta 3d 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 3-d 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 Documentacin

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

A la derecha pulsamos en download y de las dos versiones de la librera que nos aparecen, seleccionamos la versin Nightly Build.

Tras pulsar en Download ya slo nos queda descargar la ltima versin de la librera.

Crear un proyecto JAVA nuevo


Aunque el objetivo final es que el juego funcione sobre Android, trabajaremos con un proyecto JAVA que una vez terminado se portar a Android.

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 libgdxnightly > 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 JoglApplication(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.

11. 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"

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

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

12. 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.

Ciclo de vida de una aplicacin libGDX


Este apartado describe cmo se estructura una aplicacin libgdx. LA APLICACION Es el principal punto de entrada para cualquier aplicacin libgdx. La interfaz Application determina la plataforma y los graficos de fondo que sern utilizados por la aplicacin. La interfaz 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. LibGDX es compatible actualmente con dos back-ends de aplicaciones de escritorio (lwjgl y JOGL) y otra para Android. 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

Los eventos que son desencadenados por los en la aplicacin del ciclo de vida tal como se describe: 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 aplicacion


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:

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. El siguiente fragmento de cdigo borra la pantalla y la pinta de rojo:
gl.glClearColor(0.1f, 0.0f, 0.0f, 1); gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

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 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. 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 imagen de textura empaquetada */ public static AtlasRegion background; public static AtlasRegion soundoff; public static AtlasRegion soundon; public static AtlasRegion start; public static AtlasRegion 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);

Sounds
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();

Music

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; // #3 Texture walkSheet; // #4 TextureRegion[] walkFrames; // #5 SpriteBatch spriteBatch; // #6 TextureRegion currentFrame; // #7 float positionX=1; float stateTime; // #8 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() { } }

Pginas 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

Solucin de problemas
TO DO: Se describen los problemas que ms pueden aparecer junto con sus soluciones.