187 lines
6.3 KiB
JavaScript
187 lines
6.3 KiB
JavaScript
|
|
// static/js/game.js
|
|||
|
|
|
|||
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|||
|
|
const TIEMPO_TOTAL = 60; // segundos
|
|||
|
|
let segundosRestantes = TIEMPO_TOTAL;
|
|||
|
|
let puntuacion = 0;
|
|||
|
|
|
|||
|
|
const barraTiempo = document.getElementById("barra-tiempo");
|
|||
|
|
const tiempoTexto = document.getElementById("tiempo-texto");
|
|||
|
|
const contadorAciertos = document.getElementById("contador-aciertos");
|
|||
|
|
const enunciado = document.getElementById("enunciado");
|
|||
|
|
const inputRespuesta = document.getElementById("input-respuesta");
|
|||
|
|
const feedback = document.getElementById("feedback");
|
|||
|
|
const botonFinal = document.getElementById("boton-final");
|
|||
|
|
const verRankingBtn = document.getElementById("ver-ranking");
|
|||
|
|
const jugarOtraBtn = document.getElementById("jugar-otra");
|
|||
|
|
|
|||
|
|
const formNombre = document.getElementById("form-nombre");
|
|||
|
|
const inputNombre = document.getElementById("input-nombre");
|
|||
|
|
const guardarNombreBtn = document.getElementById("guardar-nombre");
|
|||
|
|
const mensajeGuardar = document.getElementById("mensaje-guardar");
|
|||
|
|
|
|||
|
|
let numeroA = 0;
|
|||
|
|
let numeroB = 0;
|
|||
|
|
let temporizadorInterval = null;
|
|||
|
|
|
|||
|
|
// Genera un par aleatorio (dos números entre 10 y 99)
|
|||
|
|
function generarPregunta() {
|
|||
|
|
numeroA = Math.floor(Math.random() * 90) + 10; // 10…99
|
|||
|
|
numeroB = Math.floor(Math.random() * 90) + 10;
|
|||
|
|
enunciado.textContent = `¿Cuánto es ${numeroA} × ${numeroB}?`;
|
|||
|
|
inputRespuesta.value = "";
|
|||
|
|
inputRespuesta.focus();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Inicia el cronómetro y actualiza cada segundo
|
|||
|
|
function iniciarTemporizador() {
|
|||
|
|
barraTiempo.style.width = "100%";
|
|||
|
|
tiempoTexto.textContent = `${segundosRestantes} segundos restantes`;
|
|||
|
|
temporizadorInterval = setInterval(() => {
|
|||
|
|
segundosRestantes--;
|
|||
|
|
if (segundosRestantes < 0) {
|
|||
|
|
clearInterval(temporizadorInterval);
|
|||
|
|
terminarJuego();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
// Actualiza texto y barra de progreso
|
|||
|
|
tiempoTexto.textContent = `${segundosRestantes} segundos restantes`;
|
|||
|
|
const porcentaje = (segundosRestantes / TIEMPO_TOTAL) * 100;
|
|||
|
|
barraTiempo.style.width = `${porcentaje}%`;
|
|||
|
|
|
|||
|
|
// Cambiar color de barra si queda poco tiempo
|
|||
|
|
if (segundosRestantes <= 10) {
|
|||
|
|
barraTiempo.classList.remove("bg-success");
|
|||
|
|
barraTiempo.classList.add("bg-danger");
|
|||
|
|
} else if (segundosRestantes <= 30) {
|
|||
|
|
barraTiempo.classList.remove("bg-success");
|
|||
|
|
barraTiempo.classList.add("bg-warning");
|
|||
|
|
}
|
|||
|
|
}, 1000);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Función que maneja el envío de la respuesta al presionar Enter
|
|||
|
|
inputRespuesta.addEventListener("keydown", (e) => {
|
|||
|
|
if (e.key === "Enter" && segundosRestantes > 0) {
|
|||
|
|
e.preventDefault();
|
|||
|
|
validarRespuesta();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
function validarRespuesta() {
|
|||
|
|
const valor = parseInt(inputRespuesta.value);
|
|||
|
|
const correcta = numeroA * numeroB;
|
|||
|
|
if (!isNaN(valor)) {
|
|||
|
|
if (valor === correcta) {
|
|||
|
|
puntuacion++;
|
|||
|
|
contadorAciertos.textContent = puntuacion;
|
|||
|
|
feedback.innerHTML = `<span class="text-success">Correcto!</span>`;
|
|||
|
|
} else {
|
|||
|
|
feedback.innerHTML = `<span class="text-danger">Incorrecto. Era ${correcta}.</span>`;
|
|||
|
|
}
|
|||
|
|
// Mostrar feedback por 800ms y luego limpiarlo
|
|||
|
|
setTimeout(() => {
|
|||
|
|
feedback.textContent = "";
|
|||
|
|
}, 800);
|
|||
|
|
} else {
|
|||
|
|
feedback.innerHTML = `<span class="text-warning">Ingresa un número válido.</span>`;
|
|||
|
|
setTimeout(() => {
|
|||
|
|
feedback.textContent = "";
|
|||
|
|
}, 800);
|
|||
|
|
}
|
|||
|
|
generarPregunta();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function terminarJuego() {
|
|||
|
|
// Deshabilitar input
|
|||
|
|
inputRespuesta.disabled = true;
|
|||
|
|
feedback.innerHTML = `
|
|||
|
|
<div class="alert alert-info p-2">
|
|||
|
|
¡Tiempo terminado! Tu puntuación es: <strong>${puntuacion}</strong>
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
|
|||
|
|
// Enviar puntuación al servidor
|
|||
|
|
fetch('/api/score', {
|
|||
|
|
method: 'POST',
|
|||
|
|
headers: { 'Content-Type': 'application/json' },
|
|||
|
|
body: JSON.stringify({ puntuacion })
|
|||
|
|
})
|
|||
|
|
.then(res => res.json())
|
|||
|
|
.then(data => {
|
|||
|
|
if (data.error) {
|
|||
|
|
feedback.innerHTML += `<div class="text-danger">Error: ${data.error}</div>`;
|
|||
|
|
botonFinal.classList.remove("d-none");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (data.entra_en_top) {
|
|||
|
|
// Muestra formulario para nombre
|
|||
|
|
formNombre.classList.remove("d-none");
|
|||
|
|
} else {
|
|||
|
|
// No entra en top10: mostrar botón para ver ranking
|
|||
|
|
botonFinal.classList.remove("d-none");
|
|||
|
|
}
|
|||
|
|
// Guarda el top10 actual en data.top10 para mostrar más tarde si hace falta
|
|||
|
|
window.top10_actual = data.top10;
|
|||
|
|
})
|
|||
|
|
.catch(err => {
|
|||
|
|
feedback.innerHTML += `<div class="text-danger">Error conectando al servidor.</div>`;
|
|||
|
|
botonFinal.classList.remove("d-none");
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Botón “Ver Ranking” (si no entró en top 10)
|
|||
|
|
verRankingBtn.addEventListener("click", () => {
|
|||
|
|
// Redirigir a la página /ranking
|
|||
|
|
window.location.href = "/ranking";
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Botón “Jugar otra vez”
|
|||
|
|
jugarOtraBtn.addEventListener("click", () => {
|
|||
|
|
window.location.href = "/juego";
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Al hacer clic en “Guardar” nombre (si entró en top 10)
|
|||
|
|
guardarNombreBtn.addEventListener("click", () => {
|
|||
|
|
const nombre = inputNombre.value.trim();
|
|||
|
|
if (nombre.length === 0) {
|
|||
|
|
mensajeGuardar.innerHTML = `<small class="text-danger">El nombre no puede estar vacío.</small>`;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
// Enviar nombre + puntuación al servidor
|
|||
|
|
fetch('/api/score/save', {
|
|||
|
|
method: 'POST',
|
|||
|
|
headers: { 'Content-Type': 'application/json' },
|
|||
|
|
body: JSON.stringify({ nombre, puntuacion })
|
|||
|
|
})
|
|||
|
|
.then(res => res.json())
|
|||
|
|
.then(data => {
|
|||
|
|
if (data.error) {
|
|||
|
|
mensajeGuardar.innerHTML = `<small class="text-danger">Error: ${data.error}</small>`;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
mensajeGuardar.innerHTML = `<div class="alert alert-success p-2">
|
|||
|
|
¡Puntuación guardada! Puedes ver el ranking actualizado.</div>`;
|
|||
|
|
// Opcional: mostrar tabla de top10 recibida en data.top10
|
|||
|
|
setTimeout(() => {
|
|||
|
|
window.location.href = "/ranking";
|
|||
|
|
}, 1500);
|
|||
|
|
})
|
|||
|
|
.catch(err => {
|
|||
|
|
mensajeGuardar.innerHTML = `<small class="text-danger">Error guardando el nombre.</small>`;
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Iniciar todo
|
|||
|
|
function iniciarJuego() {
|
|||
|
|
generarPregunta();
|
|||
|
|
iniciarTemporizador();
|
|||
|
|
inputRespuesta.disabled = false;
|
|||
|
|
inputRespuesta.focus();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Esperar 300ms para que el usuario vea la primera pregunta
|
|||
|
|
setTimeout(iniciarJuego, 300);
|
|||
|
|
});
|
|||
|
|
|