Juglar

Motor de juegos narrativos y educativos
para aprender programación web

Tiempo y secuencias

También podemos crear desafíos que usen el tiempo. Por ejemplo viendo o escuchando una secuencia y teniendo que repetirla. Como ejemplo simularemos un piano:

En el html creamos un elemento teclado con siete teclas:


<repetir-patrón>
	<button data-escena="menú-juego">Volver</button>
	
	<button id="inicia_patrón">Iniciar</button>
	<teclado-colores>
		<tecla-coloreada></tecla-coloreada>
		<tecla-coloreada></tecla-coloreada>
		<tecla-coloreada></tecla-coloreada>
		<tecla-coloreada></tecla-coloreada>
		<tecla-coloreada></tecla-coloreada>
		<tecla-coloreada></tecla-coloreada>
		<tecla-coloreada></tecla-coloreada>
	</teclado-colores>
	
	
	<link rel="stylesheet" href="repetir_patrón.css">
	<script src="repetir_patrón.js"></script>
</repetir-patrón>

Con css las colocamos en fila (flex-direction:row) y definimos un color distinto para cada tecla:

teclado-colores{
	display: flex;
	flex-direction:row;
	gap:0.1rem;
	margin:1rem auto;
	width:90%;
	
	tecla-coloreada{
		--brillo:90%;
		background-color:hsl(0deg 100% var(--brillo));
		border-radius:1rem;
		height:15rem;
		width:4rem;
		cursor:pointer;
		
		&.pulsada{
			--brillo:50%;
		}
		
		&:nth-child(2){
			background-color:hsl(40deg 100% var(--brillo));
		}
		
		&:nth-child(3){
			background-color:hsl(60deg 100% var(--brillo));
		}
		
		&:nth-child(4){
			background-color:hsl(120deg 100% var(--brillo));
		}
		
		&:nth-child(5){
			background-color:hsl(180deg 100% var(--brillo));
		}
		
		&:nth-child(6){
			background-color:hsl(240deg 100% var(--brillo));
		}
		
		&:nth-child(7){
			background-color:hsl(280deg 100% var(--brillo));
		}
		
	}
}

Fíjate además que hemos creado una clase .pulsada que cambiará el brillo de la tecla cuando la pulsemos. Para ello cambia el valor de una variable --brillo que luego se usa en la definición de los colores

En javascript tendremos un patrón con la posición de la nota a tocar. Para tocarla recorremos el patron usando un bucle for (para), que para cada elemento del patrón, pulsa la tecla:

const patrón = [3, 3, 4, 5, 5, 4, 3, 2, 1]
const puzle_patrón = selecciona("repetir-patrón")
const teclas = puzle_patrón.selecciona("tecla-coloreada")
const botón_inicia = puzle_patrón.selecciona("button#inicia_patrón")

botón_inicia.al_pulsar(reproduce_patrón)

async function reproduce_patrón() {
	await espera(0.5)
	
	for  (const número_tecla of patrón) {
		const tecla = teclas.obtén(número_tecla - 1)
		await  pulsa_tecla(tecla)
		await espera(0.5)
	}
}

async function pulsa_tecla(tecla) {
	tecla.clase.pulsada = true
	tocaNota(tecla.orden_elemento, 0.5)
	await espera(0.5)
	tecla.clase.pulsada = false
}

Ya solo nos queda repetir el patrón. Para ello guardamos el número de teclas acertadas, con lo que podemos saber cual toca despues. Si se toca la tecla correcta, seguimos avanzando, y en caso contrario sonará un fallo y repetiremos el patrón, para volver a empezar de nuevo:


let número_teclas_acertadas = 0
teclas.al_pulsar(tecla =>{
	const tecla_esperada = patrón[número_teclas_acertadas]-1
	const acierto = tecla_esperada == tecla.orden_elemento
	
	if(acierto){
		pulsa_tecla(tecla) 
		número_teclas_acertadas++
		
		if(número_teclas_acertadas==patrón.length) rompecabezas_resuelto()
	}
	else{
		sonido_fallo()
		alert('Has fallado!')
		reproduce_patrón()
	}
})

Como bonus, tenemos ahora una manera de escribir pequeñas melodías.