-
Aviso: Si utilizan Chrome en Ubuntu/Linux, utilicen siempre valores inferiores de
rate
a2
. Parece que B3cl0s3r ha descubierto un bug en Chrome bajo Ubuntu/Linux en el que la reproducción de un texto con valores superiores nunca termina (hay que hacer un.cancel()
para terminar la reproducción). -
Aviso 2: Al parecer el evento
boundary
sólo funciona en motores de ciertos sistemas operativos (Windows), mientras que parece que en Linux no tiene soporte. Si no les es posible probarlo en un sistema con soporte, los puntos 3 y 4 de la práctica pasan a ser opcionales. En su lugar, pueden implementar una funcionalidad extra libre en las conversaciones, utilizando la API multimedia ya vista u otra funcionalidad similar. No se olviden documentar en elREADME.md
que funcionalidad extra han hecho en reemplazo de boundary.
- API Multimedia · Soporte
- Mediante HTMLMediaElement (Enfoque nativo)
- Mediante HowlerJS
- Vibrate API · Soporte
- WebStorage (Local & Session) · Soporte
- Sintetizador de voz · Soporte
- Giroscopio y Acelerómetro · Soporte
- Peticiones asíncronas
- Otras APIs interesantes
En la siguiente práctica, vamos a utilizar la API de síntesis de voz del navegador para construir un sistema simple de diálogos para un juego. El objetivo es crear varios perfiles de personajes, cada uno con sus propias características particulares. Se aconseja utilizar la siguiente organización:
- Una clase
Profile
para guardar las características del personaje, donde se pueden encontrar cosas como la velocidad de diálogo, el avatar del personaje o el color del texto. Por ejemplo:
const manzProfile = new Profile("Manz", {
lang: "es",
rate: 2.0,
pitch: 1.0,
color: "#ff0000",
});
- Una clase
Conversation
para trabajar y controlar las conversaciones de todos los personajes. Una conversación se podría definir como un array de objetos, donde cada uno contiene la frase y el personaje que la pronuncia.
const conversation = new Conversation(box);
conversation.addMessage([
{ author: manzProfile, text: "¡Hola a todos! ¿Qué tal están?" },
{ author: robotProfile, text: "Muy bien, ¡gracias!" },
{ author: breadmanProfile, text: "Yo también muy bien" },
{
author: manzProfile,
text: "El robot habla con un acento un tanto raro...",
},
{ author: robotProfile, text: "Es que soy del norte" },
]);
- Implementa la clase
Profile
para definir las características del personaje. - Implementa la clase
Conversation
para definir la conversación global y su manejo del sintetizador de forma que sea ajeno a la página principal. - La forma más fácil de implementar el sistema de diálogos es haciendo que muestre cada frase de golpe. ¿Serías capaz de implementarla de forma que aparezca palabra a palabra, a medida que la pronuncia? (Pista: hay que usar eventos)
- Separa en métodos de clase para que puedas decidir si utilizar el método
wordToWord()
para que el personaje muestre el texto palabra a palabra, o el métodoletterToLetter()
para que muestre letra a letra, como en el juego Undertale. Implementa también un método para que reproduzca un sonido en cada letra. Puedes utilizar Bxfr (requiere Flash/Adobe Air) para generarlos. - Genera el
build
y haz el despliegue en GitHub Pages, de modo que se pueda ver el ejemplo en vivo.
- Web desplegada funcionando.
- Creación de varios perfiles diferentes
- Clase Profile
- Clase Conversation
- ¿Es capaz de mostrar el texto palabra a palabra?
- README
-
Implementa la API de vibración del navegador en tu ejemplo, para que vibre cada vez que un personaje pronuncie una palabra o frase. Ten muy en cuenta que la API de vibración sólo puedes comprobarla en móviles o tablets que lo soporten.
-
Reto opcional: Con el
localStorage
podríamos hacer que el navegador te solicite el nombre o nick de usuario y se guarde en el navegador, de modo que se guarde y lo recuerde incluso si cerramos el navegador y lo volvemos a abrir. ¿Sabrías implementar esta característica de modo que los personajes te llamen por tu nombre (si lo conocen) o por el nombreMr. Undefined
si no lo conocen? -
Utilizando peticiones asíncronas podríamos externalizar objetos de nuestro código en ficheros JSON externos y ajenos a la lógica del proyecto. Intenta implementarlo con las opciones de configuración de los personajes.