El tutor de nuestro curso online de Desarrollo de Aplicaciones para Android, Víctor Ramírez Las,…
Framewok libGDX para programación de videojuegos
1.
Framewok libGDX para programación de videojuegos
En esta serie de tutoriales vamos a presentar al framework libGDX para desarrollo de videojuegos y realizaremos un primer proyecto con él.
Si quieres aprender más sobre este tema, realizando tu propio proyecto y ayuda de un Tutor para resolver tus dudas, consulta nuestro curso de Programación de Juegos en Android (libGDX)
¿Qué es un Framework?
Tanto si tienes experiencia como desarrollador de software, como si no, te habrás tropezado alguna vez con el término de framework, cuya traducción aproximada sería la de «marco de trabajo». Sus objetivos principales son los de acelerar los procesos de desarrollo, promover buenas prácticas de programación a través de los patrones de diseño o incluso reutilización de código.
Si nos centramos en frameworks dedicados al desarrollo de videojuegos en la plataforma Android, están diseñados para ofrecernos ayuda en el diseño de gráficos en 2D y 3D, motor de físicas, animación gráfica y rendimiento hardware, y todo esto, ofreciéndonos una estructura ordenada para la programación de videojuegos.
Un motor de físicas es un sistema software que implementa simulaciones a ciertos sistemas físicos, cómo dinámica de sólidos rígidos (por ejemplo, la detección de colisiones) o dinámica de fluidos, en tiempo real.
Introducción a libGDX
LibGDX es un framework para el desarrollo de videojuegos escrito principalmente en Java, con algunas características que lo hacen muy atractivo, como el ser multiplataforma o estar bajo licencia Apache 2.0. De esta forma contamos con un framework libre y gratuito que nos permite trabajar con gran simplicidad, al poder escribir el código en un único proyecto, para posteriormente trasladarlo a otras plataformas sin modificar nada.
Mencionaremos algunas de las herramientas que implementa LibGDX:
- Framework para el manejo del ciclo de vida de la aplicación.
- Módulo de entrada para controlar la comunicación con el usuario, a través del acelerómetro, pantalla táctil etc.
- Proporciona una librería para el diseño, manipulación y representación de objetos gráficos.
- Módulo para reproducción y efectos de audio.
Ya adelantamos algunas de sus características. Veamos un resumen de las más destacadas:
- Soporta OpenGL ES 2.0 y 3.0 compatible con dispositivos actuales.
- Proporciona una serie de módulos (conjunto de APIs), que posibilitan el manejo de gráficos, audio y entradas de usuario tales como teclado, ratón o dispositivos con pantalla táctil.
- Es un framework multiplataforma, entre las que destacan las siguientes:
- Windows.
- Linux.
- Android (para versiones 1.5 y superiores).
- Javascript/WebGL (GWT–> Google Web Toolkit).
- Mac OS X.
- IOS (es necesario el uso de monotouch, cuya licencia es de pago).
- Uso de Sprites, Textures, fonts, sistemas de partículas etc.
- Integración de Box 2D (librería que implementa un motor físico en dos dimensiones).
- Es Open Source (licencia Apache 2.0), por lo que es posible acceder a su código fuente, además de usarlo tanto para proyectos personales como proyectos comerciales.
- Escrito principalmente en Java, implementa algunas partes en C/C++ (soporte a tareas que requieren de alto rendimiento como el motor de físicas y el procesamiento de audio)
- Gran documentación, complementada con un repositorio formado por numerosos ejemplos:
Comenzando a trabajar con libGDX
A continuación, describiremos un proyecto realizado con el framework libGDX, para desarrollar un videojuego destinado a la plataforma Android.
Antes de comenzar a describir y comentar el código del proyecto, es conveniente enumerar los elementos y pasos necesarios para la creación de dicho proyecto:
- En primer lugar se descargará del archivo «gdx-setup-ui.jar» para la creación de un proyecto con el framework libGDX: enlace de descarga –> https://github.com/AurelienRibon/gdx-setup-ui/downloads.
- Ejecutaremos el archivo comentado anteriormente, cumplimentando los datos del formulario que se mostrará, al igual que cuando se realiza un nuevo proyecto en el IDE Eclipse (pincha en la imagen para ampliarla):
- Una vez completado el formulario, abriremos nuestro entorno de desarrollo, e importaremos los proyectos creados para comenzar a implementar nuestro código (en Eclipse debemos ir al menú: File > Import… > General > Existing Projects into Workspace y seleccionaremos el directorio donde se crearon los proyectos).
- En nuestro caso, solo nos interesaría el proyecto para la plataforma Android, aunque nos proporcionará un proyecto común para el resto de plataformas, que será donde desarrollaremos el videojuego:
Estructura de proyectos con libGDX:
Como podemos comprobar en la imagen superior, el proyecto denominado «JuegoslibGDX-android«, será desde el que se invoque al proyecto común, para un videojuego en la plataforma Android. En la carpeta «assets«, se incluirán todos los recursos necesarios para el funcionamiento de nuestro juego.
Abriremos la clase creada dentro del proyecto común y definiremos la lógica de nuestro videojuego. En este ejemplo, se ha desarrollado un videojuego cuyo misión principal será la de controlar una nave espacial, evitando chocar con las naves enemigas, utilizando la pantalla táctil del dispositivo. Vemos una imagen de la misma:
Proyecto JuegoslibGDX:
JuegoslibGDX/src/com.academiaandroid.libgdx/MiJuegoGDX.java
Nota: este proyecto se explicará a lo largo de las 4 publicaciones que componen esta serie de tutoriales, por lo que algunos elementos utilizados (texturas, colisiones, métodos que se llaman durante el ciclo de vida de la aplicación,…) pueden incluirse en el código antes de que los presentemos más en detalle.
- Se define una clase llamada MiJuegoGDX, que implementará la interfaz ApplicationListener, que sobrescribe una serie de métodos para la creación, pausa y destrucción de los elementos que intervienen en el videojuego:
1 2 3 4 5 |
/*Clase que implementa la interfaz ApplicationListener, que será lanzada al crear la aplicación. Todos los métodos que sobrescribe, se implementan en el hilo de OpenGL para manipular gráficos con total seguridad.*/ public class MiJuegoGDX implements ApplicationListener{ |
-
Se declaran e inicializan las variables que representarán, tanto los elementos visuales del videojuego, como los parámetros de velocidad de movimiento de los diferentes objetos en pantalla:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/*Se declaran las variables para mostrar los diferentes mapas de bits (Sprites) y Texturas para las imágenes del juego.*/ private SpriteBatch batch; private Texture nave,objeto_enemigo, vida,fondo; private Sprite nave_jugador,nave_enemiga1,nave_enemiga2,nave_enemiga3,vida_jugador1, vida_jugador2,vida_jugador3,fondo_juego; private BitmapFont titulo; private int velocidad_nave = 200; private int velocidad_enemigo1 = 80; private int velocidad_vida1 = 60; private int velocidad_enemigo2 = 65; private int velocidad_vida2 = 100; private int velocidad_enemigo3 = 45; private int velocidad_vida3 = 75; private int altura; private OrthographicCamera camera; [...] [...] |
-
Se inicializan las texturas (dentro del método create() , que será invocado al crear la aplicación por primera vez), indicando como recurso las imágenes añadidas en el directorio assets del proyecto «JuegoslibGDX-android«:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/*Se cargan las texturas con los recursos añadidos al proyecto.*/ nave = new Texture(Gdx.files.internal("data/nave.png")); vida = new Texture(Gdx.files.internal("data/vida.png")); objeto_enemigo = new Texture(Gdx.files.internal("data/enemigo.png")); fondo = new Texture(Gdx.files.internal("data/fondo.png")); /*Inicializamos los diferentes Sprites, indicando el recurso, las coordenadas de la esquina inferior izquierda, y el tamaño de la imagen, que obligatoriamente debe ser potencia de 2.*/ vida_jugador1 = new Sprite(vida,0,0, 256, 128); nave_enemiga1 = new Sprite(objeto_enemigo,0,0,256,128); nave_jugador = new Sprite(nave,0,0,512,128); fondo_juego = new Sprite(fondo,0,0,1280,800); [...] [...] |
-
Se liberan los recursos de memoria, destruyendo los objetos creados. Este método será invocado al cerrar la aplicación:
1 2 3 4 5 6 7 8 9 10 11 12 |
/*Método que será invocado al destruir la aplicación. En él se invocan aquellos objetos que deben destruirse para que el recolector de basura lo elimine de la memoria.*/ @Override public void dispose() { batch.dispose(); nave.dispose(); objeto_enemigo.dispose(); vida.dispose(); fondo.dispose(); } [...] [...] |
-
Definimos un método para controlar la nave del jugador a través de la pantalla táctil del dispositivo. Además se actualizan las posiciones de los objetos nave_enemiga1 y vida_jugador1, mediante el cálculo de tiempo entre frame y frame, multiplicándolo por el parámetro de velocidad establecido, y desplazándolos desde el eje de coordenadas +X a -X (de derecha a izquierda de la pantalla):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
/*Método que permite controlar la nave del jugador con pulsaciones en la pantalla del dispositivo. Además se implementa la lógica de movimiento, tanto de la nave enemiga, como del objeto que proporciona tiempo extra.*/ private void controlesJugador() { boolean tocar_pantalla = Gdx.input.isTouched(); float eje_x_nave = nave_jugador.getX(); float eje_y_nave = nave_jugador.getY(); float eje_x_vida1 = vida_jugador1.getX(); float eje_y_vida1 = vida_jugador1.getY(); float eje_x_obstaculo1 = nave_enemiga1.getX(); float eje_y_obstaculo1 = nave_enemiga1.getY(); float tiempo = Gdx.graphics.getDeltaTime(); if(tocar_pantalla) { eje_y_nave = eje_y_nave + velocidad_nave * tiempo; eje_x_obstaculo1 = eje_x_obstaculo1 - velocidad_enemigo1 * tiempo; eje_x_vida1 = eje_x_vida1 - velocidad_vida1 * tiempo; nave_jugador.setPosition(eje_x_nave, eje_y_nave); }else { eje_y_nave = eje_y_nave - velocidad_nave * tiempo; eje_x_obstaculo1 = eje_x_obstaculo1 - velocidad_enemigo1 * tiempo; eje_x_vida1 = eje_x_vida1 - velocidad_vida1 * tiempo; } nave_enemiga1.setPosition(eje_x_obstaculo1, eje_y_obstaculo1); nave_jugador.setPosition(eje_x_nave, eje_y_nave); vida_jugador1.setPosition(eje_x_vida1, eje_y_vida1); } [...] [...] |
-
Por último, se define un método encargado de pintar los objetos en pantalla. Este método será invocado por el método render() , que se invocará por cada frame de pantalla:
Proyecto JuegoslibGDX-android:
JuegoslibGDX-android/src/com.academiaandroid.libgdx/MainActivity.java
Esta clase se encargará de realizar la llamada a la clase MiJuegoGDX, para la ejecución del videojuego:
1 2 3 4 5 6 7 8 9 10 11 |
/*Clase MainActivity que hereda de la clase base AndroidApplication para la inicialización del videojuego.*/ public class MainActivity extends AndroidApplication { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration(); /*Se inicializa la clase encargada de ejecutar el videojuego.*/ initialize(new MiJuegoGDX(), cfg); } } |
Atentos a la próxima publicación semanal donde continuaremos explicando este proyecto de videojuego.
Esta entrada tiene 2 comentarios
Los comentarios están cerrados.
[…] En primer lugar, comenzaremos creando el proyecto con el framework libGDX, como ya vimos en un tutorial de la serie anterior sobre libGDX: […]
[…] este video explicamos el proyecto de animación que hemos realizado con el framework libGDX y el motor de simulación de físicas Box2D, que ha sido utilizado en juegos tan conocidos como […]