Herramientas de usuario

Herramientas del sitio


sonido

Sonido

Una buena forma de enriquecer un mundo es añadirle efectos sonoros y música ambiente. En Aetheria Game Engine es sencillo conseguir esto, mediante código BeanShell. AGE soporta una gran variedad de formatos de audio y música para este propósito.

Audio

Un fichero de audio es aquél que guarda una grabación digital de sonido. Son la manera más general y más utilizada de representar sonidos, porque en ellos podemos tener almacenados efectos, música, voces, o cualquier otro tipo de sonido.

El soporte de audio de AGE permite utilizar mayor variedad de formatos de audio que otros sistemas, y permite tocar sonidos, detenerlos, repetirlos en bucle y cambiar dinámicamente el volúmen de forma muy sencilla.

Los formatos de audio actualmente soportados por AGE son: WAV, AIFF, MP3, OGG y SPX (nótese que AGE también soporta música en MIDI y MOD; pero éstos no son formatos de audio y su manejo se hace con otros métodos distintos, que se explican más adelante).

Los sonidos se pueden reproducir y gestionar directamente desde métodos de la clase Mobile, de forma que para que un jugador escuche un sonido en su cliente, invocaremos los métodos directamente sobre ese jugador.

Reproducir un sonido
/*clase Mobile*/ boolean playAudioIfAvailable ( URL sound )

m.playAudioIfAvailable( sound ) toca el sonido referenciado por sound en el cliente asociado con la criatura m (que normalmente será un jugador), si esto es posible.

En el caso de que sea posible y el cliente del jugador tenga el volumen activado, comenzará a sonar el audio y el método devolverá inmediatamente true (sin esperar a que la reproducción termine).

En el caso de que no sea posible reproducir el sonido, no sonará nada y el método devolverá false. Esto puede suceder por las siguientes razones:

  • La criatura es un personaje no jugador y por lo tanto no puede escuchar sonidos,
  • La criatura es un jugador pero está jugando a través de un cliente que no soporta sonidos (por ejemplo, conectado por medio de telnet),
  • La URL pasada como parámetro es errónea, o apunta a un fichero que no existe, o apunta a un fichero que no es de ninguno de los formatos de audio reconocidos por AGE.

Cabe recordar que para obtener el objeto de la clase URL que apunta a un fichero que incluimos con el mundo, podemos utilizar el método getResource() de la clase World. Así, para reproducir un sonido llamado “musica.ogg” que incluimos con el mundo, haríamos:

jugador.playAudioIfAvailable( world.getResource("musica.ogg") );

Nótese que en este caso estamos ignorando el valor de retorno (true o false) porque no nos importa: simplemente queremos que si el jugador está jugando en un cliente que soporta sonido, pueda oírlo, y si no, tampoco pasa nada. El valor de retorno sólo será importante si queremos programar algún comportamiento alternativo para clientes que no tengan sonido.

/*clase Mobile*/ boolean playAudioIfAvailable ( URL sound , int loopTimes )

Este método hace lo mismo que boolean playAudioIfAvailable ( URL sound ); pero nos permite especificar a mayores un parámetro entero loopTimes que sirve para hacer que un sonido se repita un determinado número de veces:

  • Si pasamos loopTimes = 1, el sonido se reproducirá una vez (es decir, igual que con el método sin parámetro),
  • Si pasamos loopTimes > 1, el sonido se reproducirá loopTimes veces,
  • Si pasamos loopTimes < 1, el sonido se repetirá indefinidamente (pero se puede parar usando stopAudioIfAvailable(), que se verá más abajo).
/*clase Mobile*/ boolean playAudioIfAvailable ( URL sound , int loopTimes , boolean fade )

Este método hace lo mismo que boolean playAudioIfAvailable ( URL sound , int loopTimes ); pero nos permite especificar un parámetro booleano adicional fade. Si este parámetro se pone a true, el sonido se reproducirá con un “fade in” (transición de inicio). Si se pone a false, el método se comportará igual que la versión sin este parámetro.

Detener un sonido
/*clase Mobile*/ boolean stopAudioIfAvailable ( URL sound )

m.stopAudioIfAvailable( sound ) para la reproducción del sonido referenciado por sound en el cliente asociado con la criatura m (que normalmente será un jugador), si este sonido se encuentra sonando.

En el caso de que el sonido esté sonando, además de detenerlo, el método devuelve true. Si no está sonando (bien porque no ha llegado a reproducirse o porque ya ha terminado su reproducción), el método no tiene efecto y devuelve false.

/*clase Mobile*/ boolean stopAudioIfAvailable ( URL sound , boolean fade )

Este método hace lo mismo que boolean stopAudioIfAvailable ( URL sound ); pero nos permite especificar un parámetro booleano adicional fade. Si este parámetro se pone a true, el sonido se reproducirá con un “fade out” (transición de final). Si se pone a false, el método se comportará igual que la versión sin este parámetro.

Cambiar el volumen de un sonido
/*clase Mobile*/ boolean setAudioGainIfAvailable ( URL sound , double gain )

m.setAudioGainIfAvailable ( sound , gain ) permite cambiar el volumen del sonido referenciado por sound que esté sonando en el cliente asociado con la criatura m (que normalmente será un jugador), si esto es posible. El volumen toma el valor gain, que ha de estar entre 0.0 y 1.0, siendo 0.0 el volumen nulo (sin sonido) y 1.0 el volumen máximo. El método devolverá true si el volumen se ha podido cambiar, y false de lo contrario.

Nótese que para cambiar el volumen, el sonido tiene que estar sonando. Sin embargo, podemos cambiar el volumen de un sonido desde el principio llamando inmediatamente a setAudioGainIfAvailable después de playAudioIfAvailable:

jugador.playAudioIfAvailable( world.getResource("musica.ogg") );
jugador.setAudioGainIfAvailable( world.getResource("musica.ogg") , 0.2 );

Como nada más lanzar el sonido ya llamamos al cambio de volumen, el efecto de este código será que el audio “musica.ogg” se reproduzca con volumen 0.2.

Si en lugar de llamar a setAudioGainIfAvailable inmediatamente lo llamamos más adelante, con el sonido a medias, el volumen cambiará dinámicamente.

Ejemplo

Supongamos que queremos parar un sonido que estaba sonando (sonido1.mp3) y comenzar a reproducir otro (sonido2.mp3) con volumen 0.5. Entonces, haríamos lo siguiente:

//parar un sonido si está tocando
jugador.stopAudioIfAvailable( world.getResource("sonido1.mp3") );
 
//tocar un sonido, si existe el fichero y el jugador usa un cliente que soporta audio
jugador.playAudioIfAvailable( world.getResource("sonido2.mp3") );
jugador.setAudioGainIfAvailable( world.getResource("sonido2.mp3") , 0.5 );

Cabe destacar que también es posible reproducir varios sonidos a la vez. Esto puede ser interesante si, por ejemplo, tenemos un sonido de música ambiente pero queremos que además se produzcan efectos sonoros al llevar a cabo acciones.

Música MIDI

Los ficheros de música MIDI (con extensión .mid) son archivos que, en lugar de almacenar una grabación de sonido (como los ficheros de audio), guardan música en forma de una partitura que el ordenador puede reproducir.

Esta manera de representar la música es mucho más limitada que los ficheros de audio, porque no se guarda una representación fidedigna de los sonidos sino sólo notas y orientaciones sobre a qué instrumento corresponden, y suele suceder que la interpretación de esos instrumentos suena de manera muy distinta dependiendo de la tarjeta de sonido, sistema operativo y configuración de cada máquina. Por otra parte, la ventaja que tienen los ficheros MIDI es que ocupan mucho menos espacio que los ficheros de audio.

Los métodos para reproducir y detener música MIDI en AGE son similares a los correspondientes al audio, aunque proporcionan menos funcionalidad:

  • No se soportan funciones como los “fade-in” y “fade-out” porque el volumen de los ficheros MIDI se comporta de una manera muy distinta en cada sistema operativo y configuración y es difícil garantizar un comportamiento fidedigno de ese tipo de funciones.
  • Sólo se puede reproducir un fichero MIDI a la vez, al contrario que con los ficheros de audio, que pueden sonar varios a la vez. Por lo tanto, antes de reproducir una nueva música en MIDI se debe siempre llamar al método que detiene la anterior, que veremos más abajo. Nótese que esto no afecta a la combinación de MIDI y audio: no se puede tener varios MIDI sonando a la vez, pero sí un solo MIDI sonando a la vez que uno o varios ficheros de audio.

Por todo esto, en general sólo es recomendable utilizar música en formato MIDI en AGE en casos en los que sea necesario que el mundo ocupe poco espacio en disco. De lo contrario, es mucho más recomendable usar formatos de audio: en caso de duda, siempre audio, ya que es más flexible, suena mejor y es más fiable.

Reproducir un fichero MIDI
/*clase Mobile*/ boolean playMidiIfAvailable ( URL sound )

m.playMidiIfAvailable( sound ) toca el fichero MIDI por sound en el cliente asociado con la criatura m (que normalmente será un jugador), si esto es posible.

En el caso de que no sea posible reproducir la música, no sonará nada y el método devolverá false. Esto puede suceder por las siguientes razones:

  • La criatura es un personaje no jugador y por lo tanto no puede escuchar sonidos,
  • La criatura es un jugador pero está jugando a través de un cliente que no soporta sonidos (por ejemplo, conectado por medio de telnet),
  • La URL pasada como parámetro es errónea, o apunta a un fichero que no existe, o apunta a un fichero que no es un fichero MIDI válido.

También puede suceder que no se pueda reproducir la música porque esté sonando otra (como ya se ha dicho, sólo se puede reproducir un fichero MIDI a la vez). En este caso, el comportamiento depende del sistema operativo y de la configuración: puede ser que el método se niegue a reproducir el sonido y devuelva false, o bien que se pare el sonido anterior y empiece a sonar el nuevo, o bien incluso que se paren los dos. Por lo tanto, lo más razonable es no intentar reproducir nunca dos MIDIs a la vez, ya que no hay garantía de que el comportamiento vaya a ser el mismo en una máquina que en otra.

/*clase Mobile*/ boolean playMidiIfAvailable ( URL sound , int loopTimes )

Este método hace lo mismo que boolean playMidiIfAvailable ( URL sound ); pero nos permite especificar a mayores un parámetro entero loopTimes que sirve para hacer que una música en MIDI se repita un determinado número de veces:

  • Si pasamos loopTimes = 1, el MIDI se reproducirá una vez (es decir, igual que con el método sin parámetro),
  • Si pasamos loopTimes > 1, el MIDI se reproducirá loopTimes veces,
  • Si pasamos loopTimes < 1, el MIDI se repetirá indefinidamente (pero se puede parar usando stopMidiIfAvailable(), que se verá más abajo).
Detener un fichero MIDI
/*clase Mobile*/ boolean stopMidiIfAvailable ( )

m.stopMidiIfAvailable( sound ) para la música MIDI que esté sonando en el cliente asociado con la criatura m (que normalmente será un jugador).

En el caso de que algún MIDI esté sonando, además de detenerlo, el método devuelve true. Si no está sonando (bien porque no ha llegado a reproducirse o porque ya ha terminado su reproducción), el método no tiene efecto y devuelve false.

sonido.txt · Última modificación: 2011/08/19 13:07 por al-khwarizmi