
Implementar un gestor de audio nativo en Java para reproducir:
loop continuo).<aside> 💡
⚠️ Limitación: Solo soporta formatos WAV, AU, AIFF.
Para MP3/OGG se requieren librerías adicionales (ej. JavaFX Media, JLayer).
</aside>
res/
└── sound/
├── musica_fondo.wav # Índice 0
├── recoger_llave.wav # Índice 1
├── recoger_powerup.wav # Índice 2
├── abrir_puerta.wav # Índice 3
└── abrir_cofre.wav # Índice 4
🔧 Si usas MP3, conviértelos con:
ffmpeg -i musica.mp3 -acodec pcm_s16le -ar 44100 musica_fondo.wav
src/main/Sound.java (sin cambios)package main;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
/**
* Gestor de audio del juego.
* Maneja la reproducción de música de fondo y efectos de sonido.
*/
public class Sound {
Clip clip;
URL[] soundURL = new URL[30]; // Array para almacenar rutas de audio
/**
* Constructor: Inicializa las rutas de los archivos de sonido.
*/
public Sound() {
// Índice 0: Música de fondo
soundURL[0] = getClass().getResource("/sound/musica_fondo.wav");
// Índice 1: Efecto de recoger llave
soundURL[1] = getClass().getResource("/sound/recoger_llave.wav");
// Índice 2: Efecto de recoger power-up (botas)
soundURL[2] = getClass().getResource("/sound/recoger_powerup.wav");
// Índice 3: Efecto de abrir puerta
soundURL[3] = getClass().getResource("/sound/abrir_puerta.wav");
// Índice 4: Efecto de abrir cofre
soundURL[4] = getClass().getResource("/sound/abrir_cofre.wav");
}
/**
* Carga un archivo de audio en memoria.
* @param i - Índice del sonido en el array soundURL.
*/
public void setFile(int i) {
try {
AudioInputStream ais = AudioSystem.getAudioInputStream(soundURL[i]);
clip = AudioSystem.getClip();
clip.open(ais);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Inicia la reproducción del clip cargado.
*/
public void play() {
clip.start();
}
/**
* Reproduce el clip en bucle infinito (para música de fondo).
*/
public void loop() {
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
/**
* Detiene la reproducción del clip.
*/
public void stop() {
clip.stop();
}
}
PanelJuego.java:
musica: para reproducción continua (música de fondo).efectoSonido: para clips puntuales (evita colisiones entre efectos simultáneos).setFile(i) carga el clip en cada llamada → sencillo, pero puede introducir latencia leve si hay muchos triggers rápidos.
✅ Para optimización: pre-cargar clips en el constructor o usar un pool de Clip.PanelJuego.java