Bienvenidos sean a este post, en este post crearemos la clase que sera nuestro Engine de Sonido para poder manipular los sonidos como hicimos en el proyecto anterior.
Antes de comenzar con nuestra clase descarguen el siguiente archivo:
Una vez descargado el archivo, extraigan los archivos en la pc, antes de continuar vamos a crear la carpeta de assets, para ello haremos click con el boton derecho y seleccionamos New -> Folder -> Assets Folder, despues de esto aparecera el siguiente cuadro

Puede suceder que Target Source Set no les aparezca pero en caso de verse como en la imagen les recomiendo dejarlo en main, dejen todo como aparece y presionen Finish para crear la nueva carpeta, nos debera quedar de la siguiente manera

Con nuestra carpeta creada vamos a proceder a agregar los archivos de sonido, para ello vamos a donde extrajimos los archivos, los seleccionamos y presionamos Ctrl+C para copiarlos, luego vamos a la carpeta de recurso que creamos anteriormente y presionamos Ctrl+V, nos aparecera un nuevo cuadro donde no modificaremos nada y presionaremos Ok para copiarlos, una vez hecho nos quedara de la siguiente forma

Con esto concluido ya tenemos los sonidos de nuestro juego, ahora procederemos a crear la clase que se encargara de manejar los sonidos, para ello la crearemos con las siguientes caracteristicas:
- Nombre: SoundEngine
- Tipo: Class
Una vez creada la clase modificaremos el codigo generado con el siguiente:
package org.example.pepeaventura;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.util.Log;
import java.io.IOException;
class SoundEngine {
private static SoundPool mSP;
private static int mSalto_ID = -1;
private static int mLograr_ID = -1;
private static int mMoneda_ID = -1;
private static int mFallar_ID = -1;
private static SoundEngine nuestraInstancia;
public static SoundEngine getInstancia(Context contexto){
nuestraInstancia = new SoundEngine(contexto);
return nuestraInstancia;
}
public SoundEngine(Context c){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
AudioAttributes atributos = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
mSP = new SoundPool.Builder()
.setMaxStreams(5)
.setAudioAttributes(atributos)
.build();
} else {
mSP = new SoundPool(5, AudioManager.STREAM_MUSIC,0);
}
try {
AssetManager assetManager = c.getAssets();
AssetFileDescriptor descriptor;
descriptor = assetManager.openFd("saltar.ogg");
mSalto_ID = mSP.load(descriptor,0);
descriptor = assetManager.openFd("moneda.ogg");
mMoneda_ID = mSP.load(descriptor,0);
descriptor = assetManager.openFd("lograr.ogg");
mLograr_ID = mSP.load(descriptor,0);
descriptor = assetManager.openFd("fallar.ogg");
mFallar_ID = mSP.load(descriptor,0);
} catch (IOException e){
Log.e("PepeAdventure","Ha ocurrido algun error con los archivos");
}
}
}
Esta clase no va a ser muy distinta a como trabajamos hasta ahora donde primero tendremos un objeto del tipo SoundPool para manejar los sonidos, luego cuatro variables de tipo int para almacenar los «ids» de los sonidos, por ultimo crearemos un objeto de tipo SoundEngine para hacer trabajar a esta clase como si fuera un Singleton, esto lo haremos para evitar generar la larga lista de parametros que teniamos en el proyecto anterior cada vez que pasabamos una referencia del SoundEngine para cada clase/metodo, el metodo getNuestraInstancia trabaja para poder acceder a nuestro constructor a traves de la instancia tal como hicimos cuando creamos el Singleton anterior en este post, por ultimo tenemos el constructor que trabaja de la misma forma pero con una sutil diferencia en este caso, primero chequea la version del Android si es mayor o igual a LOLLIPOP, procede a definir nuestro SoundPool por medio de Builder y AudioAttributes, en caso de que sea menor a LOLLIPOP procede a crearlo por medio de la forma antigua.
Nota: Si tienen alguna duda de como trabaja pueden ver este post o alguno de los anteriores cuando asignamos los sonidos a los juegos.
La diferencia va a radicar en como conseguir los id de los archivos, dado que ahora no trabajamos con la carpeta raw sino con assets, para ello usaremos un try/catch, en el catch usaremos a IOException para interceptarlo ante cualquier error y lo mostraremos de forma generica en el Log, en el bloque del try tenemos un variable de tipo AssetManager donde por medio del contexto y getAssets obtenemos todos los recursos dentro de la carpeta assets, despues tenemos una variable de tipo AssetFileDescriptor al cual llamaremos descriptor, luego tendremos cuatro bloques para cargar los sonidos, como son todos los mismos pero con distintos archivos solo hablaremos de uno:
descriptor = assetManager.openFd("saltar.ogg");
mSalto_ID = mSP.load(descriptor,0);
La primer linea define a descriptor donde por medio de la variable de tipo AssetManager y el metodo openFd le pasaremos el nombre del archivo para obtener el id del mismo, despues de esto tomaremos la variable correspondiente al sonido para almacenarlo donde por medio de load y el id en descriptor quedara asignado a esa variable, lo mismo haremos para los tres sonidos restantes con esto ya tenemos nuestro constructor explicado, por ultimo vamos a agregar los cuatro metodos para reproducir los sonidos:
public static void playSalto(){
mSP.play(mSalto_ID,1,1,0,0,1);
}
public static void playLogrado(){
mSP.play(mLograr_ID,1,1,0,0,1);
}
public static void playJugadorQuemar(){
mSP.play(mFallar_ID,1,1,0,0,1);
}
public static void playMonedaRecogida(){
mSP.play(mMoneda_ID,1,1,0,0,1);
}
En este caso tenemos un metodo para cada sonido, son exactamente lo mismo donde usaremos a play de SoundPool pero mandaremos el id de cada sonido, con esto ya concluimos el codigo encargado de los sonidos, veamos como quedo su codigo final:
SoundEngine.java
package org.example.pepeaventura;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.util.Log;
import java.io.IOException;
class SoundEngine {
private static SoundPool mSP;
private static int mSalto_ID = -1;
private static int mLograr_ID = -1;
private static int mMoneda_ID = -1;
private static int mFallar_ID = -1;
private static SoundEngine nuestraInstancia;
public static SoundEngine getInstancia(Context contexto){
nuestraInstancia = new SoundEngine(contexto);
return nuestraInstancia;
}
public SoundEngine(Context c){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
AudioAttributes atributos = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
mSP = new SoundPool.Builder()
.setMaxStreams(5)
.setAudioAttributes(atributos)
.build();
} else {
mSP = new SoundPool(5, AudioManager.STREAM_MUSIC,0);
}
try {
AssetManager assetManager = c.getAssets();
AssetFileDescriptor descriptor;
descriptor = assetManager.openFd("saltar.ogg");
mSalto_ID = mSP.load(descriptor,0);
descriptor = assetManager.openFd("moneda.ogg");
mMoneda_ID = mSP.load(descriptor,0);
descriptor = assetManager.openFd("lograr.ogg");
mLograr_ID = mSP.load(descriptor,0);
descriptor = assetManager.openFd("fallar.ogg");
mFallar_ID = mSP.load(descriptor,0);
} catch (IOException e){
Log.e("PepeAdventure","Ha ocurrido algun error con los archivos");
}
}
public static void playSalto(){
mSP.play(mSalto_ID,1,1,0,0,1);
}
public static void playLogrado(){
mSP.play(mLograr_ID,1,1,0,0,1);
}
public static void playJugadorQuemar(){
mSP.play(mFallar_ID,1,1,0,0,1);
}
public static void playMonedaRecogida(){
mSP.play(mMoneda_ID,1,1,0,0,1);
}
}
En resumen, hoy hemos creado la clase encargada de manejar los sonidos, la diferencia en comparacion con los juegos anteriores es que trabajamos con assets en lugar del recurso raw, tambien lo hicimos trabajar como Singleton para facilitar nuestra forma de trabajo, espero les haya gustado sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.
Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.


Donación
Es para mantenimento del sitio, gracias!
$1.00
