Assets
Saludos otra vez, éste artículo lo dedicaré a los assets, un ejemplo de assets son las imágenes, el sonido y la música entre otros, que son los que a continuación voy a explicar.
Imágenes
Existen 2 tipos de imágenes planas estáticas en libgdx, la Texture y la TextureRegion.
La Texture es una imagen jpg o png que debemos cargar en memoria y luego dibujarla en el render con el objeto Spritebatch. Para cargarla en memoria antes tenemos que guardarla en nuestro proyecto de android en la carpeta assets, es recomendable separar los assets en carpetas por tipos, así que yo crearé mis carpetas Music, Sounds and Images.
Vamos a preparar nuestra imagen de fondo para el juego, he pensado hacer un juego de un pequeño pez en el oceano que tenga que recojer plancton para alimentarse, un ejemplo muy chorra pero nos servirá para ir desarrollando poco a poco.
La imagen debe ser POT, es decir, potencia de 2, no podemos hacer una imagen de 800x480 y colocarla y ya está, debemos alojarla en otra imagen con unas dimensiones de 512,1024,16,64, etc.
Así que cojo el Photoshop o el GIMP me creo mi fondo de 800x480.
Y después lo añado a una imagen de 1024x1024.
Y la guardo en la carpeta Assets/Images.
Ahora antes de instanciar la imagen ajustaré la resolución de la camara.
Para ello borraré todos los datos creados por el proyecto de prueba dejando únicamente los métodos y eliminando los atributos de la clase de mi juego. Os muestro mi clase para que observeís como colocar la imagen de fondo, guiaros por los comentarios.
package com.Firedark.libgdxspain;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
public class LibgdxSpain implements ApplicationListener {
//Creamos los 4 Objetos que usaremos para éste Tutorial, Camara, SpriteBatch,Textura y Region
private OrthographicCamera camera;
private SpriteBatch batch;
private Texture texture;
private TextureRegion region;
@Override
public void create() {
// Estas variables las usaremos para ajustar la resolución a 800x480
float w = 800;
float h = 480;
//Instanciamos Camara y le ajustamos con el metodo SetToOrtho la resolución anterior.
camera = new OrthographicCamera();
camera.setToOrtho(false,w,h);
//Instanciamos Spritebatch
batch = new SpriteBatch();
//Instanciamos la Textura, para ello tenemos que darle la localización dentro de la carpeta ASSETS
texture = new Texture(Gdx.files.internal("data/Images/oceanbackground.jpg"));
//Usaremos la region para determinar la zona que queremos cojer de la imagen de 1024 x 1024 como empieza por la
//esquina superior izquierda escojemos 0,0 de coordenadas X e Y y 800 de ancho y 480 de alto.
region = new TextureRegion(texture,0,0,800,480);
}
@Override
public void dispose() {
// NO olvidaros vaciar la memoria en el metodo dispose de los objetos que vamos subiendo a memoria.
batch.dispose();
texture.dispose();
}
@Override
public void render() {
//Esto limpiaria lo que es la pantalla en negro, al colocarle la imagen de fondo encima no lo apreciaremos
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// Ajustamos la camara con el SpriteBatch
batch.setProjectionMatrix(camera.combined);
//Empezamos a dibujar
batch.begin();
//usamos el metodo del spritebatch draw para dibujar la region,(OJO! no la textura, podriamos dibujarla también
//pero deberiamos cuadrarla en la pantalla con las coordenadas (0,-544).
batch.draw(region,0,0);
//Fin de dibujar.
batch.end();
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
}
Bien, ahora que tenemos el fondo voy a explicar como instanciar la música y el sonido, es más sencillo aún que colocar una imagen.Sonido.
Debe ser un archivo .wav, .mp3 o OGG. Es recomendable que useís algún programa para transformarlos todos a mp3 ya que ocupan menos, yo utilizo el AVS Audio Converter y la verdad es que me va genial.
Debemos crear un objeto Sound.
private Sound sound;
Metodo Create:
sound = Gdx.audio.newSound(Gdx.files.internal("data/mysound.mp3"));
Hay varios metodos para usar el sonido, es cuestión de experimentar un poco, los más
comunes son sound.play(), sound.play(float Volumen).
Aquí teneís el link del objeto sound:
http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/audio/Sound.html
Musica
Voy a colocar una música de fondo a mi juego. Me la he descargado de la página de freesounds.
http://www.freesound.org/people/KaiLietzke/sounds/185063/
Una vez descargada la renombro a musica.wav y la meto en la carpeta assets/data/Music.
Creo el objeto Music de libgdx en los atributos de mi clase, y en el metodo create añado ésto.
//Instancia la música.
musica = Gdx.audio.newMusic(Gdx.files.internal("data/Music/musica.wav"));
//La pone en bucle continuo
musica.setLooping(true);
//La pone en play.
musica.play();
Problemas y Consejos
- No metaís en memoria assets en métodos cíclicos o sobrecargareís la memoria.
- No añadais un sónido o una música en el metodo render sin condición alguna, al ser cíclico lógicamente lo pondreís en play cada ciclo y sonará mal. ( Existe un método isLooping que te devuelve un boolean si la música esta en loop)
- Acordaós de usar el método dispose() de Músicas y Sonidos.
- Cuidado con los Path de los archivos de los assets, en desktop no te detectará mayúsculas, pero en android si, y os podeís liar.
Gestor de Assets
Es conveniente intentar separar los datos de la lógica del juego para tener mayor control de la carga de assets y acceder fácilmente a ellos desde cualquier punto del programa, ahora con 1 classe principal creada no es muy necesario pero con el tiempo y con el juego mas avanzado resultará realmente útil. Para ello vamos a crear una classe llamada AssetsManager en el proyecto núcleo de nuestro juego.
Aqui crearemos nuestros objetos de texturas y nuestros 2 métodos de carga y liberación de memoria de nuestras imágenes, música y sonido.
Éste es un ejemplo de la clase del tutorial anterior:
package com.Firedark.libgdxspain;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
public class AssetsManager {
public Texture Tbackground;
public TextureRegion background;
public Music musica;
public void cargarAssets(){
Tbackground = new Texture(Gdx.files.internal("data/Images/oceanbackground.jpg"));
background = new TextureRegion(Tbackground,0,0,800,480);
musica = Gdx.audio.newMusic(Gdx.files.internal("data/Music/musica.wav"));
}
public void disposeAssets(){
Tbackground.dispose();
musica.dispose();
}
}
Finalmente deberemos ir a la classe principal de nuestro juego y acceder a los datos a través de la instancia de esta classe AssetsManager.
package com.Firedark.libgdxspain;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class LibgdxSpain implements ApplicationListener {
//Creamos los 4 Objetos que usaremos para éste Tutorial, Camara, SpriteBatch,Textura y Region
private OrthographicCamera camera;
private SpriteBatch batch;
private AssetsManager assets;
@Override
public void create() {
// Creamos el AssetManager
assets = new AssetsManager();
//Si nos olvidamos de cargar los assets en memoria nos dará NullPointerException porque no los encontrará.
assets.cargarAssets();
float w = 800;
float h = 480;
camera = new OrthographicCamera();
camera.setToOrtho(false,w,h);
batch = new SpriteBatch();
//accedemos a assets.musica, el atributo de musica de la clase assets.
assets.musica.setLooping(true);
assets.musica.play();
}
@Override
public void dispose() {
batch.dispose();
//Llamamos al metodo para liberar Assets.
assets.disposeAssets();
}
@Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
//Aqui accedemos al atributo TextureRegion background de la clase assets.
batch.draw(assets.background,0,0);
batch.end();
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
}
Gracias, para el siguiente artículo explicaré un poco de entradas y empezaremos a mover rectángulos y hacer que actúen. A programar!