Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
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.
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
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.
Nombre de la clase: Demo1Desktop Mismo paquete que la clase principal Seleccionamos la opcin public static void main(String[] args)
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
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);
} }
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.
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:
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.
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.
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 ().
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)
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.
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:
BILINEAR: La imagen aparece ms difuminada. Es un poco ms lento, pero no vers pxeles en la misma.
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
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 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:
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.
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.
/** * 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 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.
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.
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.
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; }
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.
//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() { } }