const audio = document.getElementById("musica"); const startButton = document.getElementById("startButton"); const debugTextArea = document.getElementById("debug"); const canvas = document.getElementById("tablero"); const ctx = canvas.getContext("2d"); ctx.scale(20, 20); const marcador = document.getElementById("score"); const FILAS = 20; const COLUMNAS = 10; const FPS = 60; const PIEZAS = [ [[1, 1, 1, 1]], [ [2, 2, 2], [0, 0, 2], ], [ [3, 3, 3], [3, 0, 0], ], [ [4, 4], [4, 4], ], [ [5, 5, 0], [0, 5, 5], ], [ [0, 6, 6], [6, 6, 0], ], [ [7, 7, 7], [0, 7, 0], ], ]; const COLORES_PIEZAS = { 0: "#282829", // Fondo oscuro 1: "#FFFFFF", // Blanco para cyan 2: "#FFA500", // Naranja 3: "#FFFF00", // Amarillo 4: "#00FF00", // Verde 5: "#FF0000", // Rojo 6: "#800080", // Púrpura 7: "#0000FF", // Azul }; const KEYDOWNHANDLER = (event) => { if (event.key === "ArrowDown") { moverPiezaAbajo(); } else if (event.key === "ArrowLeft") { moverPiezaIzquierda(); } else if (event.key === "ArrowRight") { moverPiezaDerecha(); } else if (event.key === " ") { rotarPieza(); } else if (event.key === "1") { toggleDebug(); } else if (event.key === "Escape") { gameOver(); } }; let debugFlag = false; let lineasVelocidad = 10; let velocidadCaida = 400; let intervalBuclePrincipal; let tiempoUltimoMovimiento = 0; let tablero = []; let puntuacion = 0; let piezaJugador; let piezaJugadorX; let piezaJugadorY; audio.preload = "auto"; function generaPiezaAleatoria() { const indice = Math.floor(Math.random() * PIEZAS.length); return PIEZAS[indice]; } function dibujaPiezaEnTablero(pieza, offsetX, offsetY) { pieza.forEach((fila, y) => { fila.forEach((valor, x) => { if (valor) { dibujarCuadro(x + offsetX, y + offsetY, valor); } }); }); } function soltarNuevaPieza() { piezaJugador = generaPiezaAleatoria(); piezaJugadorX = Math.floor(COLUMNAS / 2) - 1; piezaJugadorY = 0; } function dibujarTablero() { for (let fila = 0; fila < FILAS; fila++) { for (let columna = 0; columna < COLUMNAS; columna++) { dibujarCuadro(columna, fila, tablero[fila][columna]); } } } function dibujarCuadro(x, y, color) { ctx.fillStyle = COLORES_PIEZAS[color]; ctx.fillRect(x, y, 1, 1); } function actualizaMarcador() { marcador.textContent = puntuacion; } function inicializarTablero() { for (let fila = 0; fila < FILAS; fila++) { tablero[fila] = []; for (let columna = 0; columna < COLUMNAS; columna++) { tablero[fila][columna] = 0; } } puntuacion = 0; dibujarTablero(); actualizaMarcador(); soltarNuevaPieza(); } function moverPiezaAbajo() { piezaJugadorY++; if (colisiona(piezaJugador, piezaJugadorX, piezaJugadorY)) { if (piezaJugadorY <= 1) { gameOver(); } piezaJugadorY--; fijarPiezaTablero(); soltarNuevaPieza(); } } function moverPiezaIzquierda() { piezaJugadorX--; if (colisiona(piezaJugador, piezaJugadorX, piezaJugadorY)) { piezaJugadorX++; // Deshacer el movimiento si hay colisión } } function moverPiezaDerecha() { piezaJugadorX++; if (colisiona(piezaJugador, piezaJugadorX, piezaJugadorY)) { piezaJugadorX--; // Deshacer el movimiento si hay colisión } } function rotarPieza() { const piezaRotada = []; for (let y = 0; y < piezaJugador[0].length; y++) { piezaRotada[y] = []; for (let x = 0; x < piezaJugador.length; x++) { piezaRotada[y][x] = piezaJugador[piezaJugador.length - 1 - x][y]; } } if (!colisiona(piezaRotada, piezaJugadorX, piezaJugadorY)) { piezaJugador = piezaRotada; } } function colisiona(pieza, offsetX, offsetY) { for (let y = 0; y < pieza.length; y++) { for (let x = 0; x < pieza[y].length; x++) { if ( pieza[y][x] && (tablero[y + offsetY] && tablero[y + offsetY][x + offsetX]) !== 0 ) { return true; } } } return false; } function fijarPiezaTablero() { piezaJugador.forEach((fila, y) => { fila.forEach((valor, x) => { if (valor) { tablero[piezaJugadorY + y][piezaJugadorX + x] = valor; } }); }); revisarLineasCompletas(); } function revisarLineasCompletas() { let lineasCompletas = 0; for (let y = FILAS - 1; y >= 0; y--) { let filaCompleta = true; for (let x = 0; x < COLUMNAS; x++) { if (tablero[y][x] === 0) { filaCompleta = false; break; } } if (filaCompleta) { tablero.splice(y, 1); tablero.unshift(Array(COLUMNAS).fill(0)); y++; lineasCompletas++; } } if (lineasCompletas) { lineasVelocidad -= lineasCompletas; if (lineasVelocidad <= 0) { lineasVelocidad = 10; velocidadCaida -= 10; } switch (lineasCompletas) { case 1: puntuacion += 10; break; case 2: puntuacion += 40; break; case 3: puntuacion += 60; break; case 4: puntuacion += 80; break; } actualizaMarcador(); } } function actualizar() { const ahora = Date.now(); const deltaTiempo = ahora - tiempoUltimoMovimiento; if (deltaTiempo > velocidadCaida) { tiempoUltimoMovimiento = ahora; moverPiezaAbajo(); } ctx.clearRect(0, 0, canvas.width, canvas.height); dibujarTablero(); dibujaPiezaEnTablero(piezaJugador, piezaJugadorX, piezaJugadorY); debugLog(); } function iniciarPartida() { startButton.blur(); startButton.style.visibility = "hidden"; document.addEventListener("keydown", KEYDOWNHANDLER); musica.play(); inicializarTablero(); intervalBuclePrincipal = setInterval(actualizar, 1000 / FPS); } function gameOver() { clearInterval(intervalBuclePrincipal); document.removeEventListener("keydown", KEYDOWNHANDLER); startButton.style.visibility = "visible"; musica.pause(); musica.currentTime = 0; startButton.focus(); } function toggleDebug() { if (debugFlag) { debugFlag = false; debugTextArea.style.display = "none"; } else { debugFlag = true; debugTextArea.style.display = "block"; } } function debugLog() { debugTextArea.value = `Filas: ${FILAS}\n` + `Columnas: ${COLUMNAS}\n` + `PosX: ${piezaJugadorX} - PosY: ${piezaJugadorY} \n` + `Lineas hasta aumento de velocidad: ${lineasVelocidad}\n` + `Velocidad ms/fila: ${velocidadCaida}\n`; }