commit a978d0b7a5d2f0a4f1a5ebe11ff5e0d5292526ac Author: Marklogo Date: Sat Mar 9 12:14:14 2024 +0100 Version Beta diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/assets/Tetris.mp3 b/assets/Tetris.mp3 new file mode 100644 index 0000000..2491a3f Binary files /dev/null and b/assets/Tetris.mp3 differ diff --git a/game.js b/game.js new file mode 100644 index 0000000..86cf498 --- /dev/null +++ b/game.js @@ -0,0 +1,284 @@ +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`; +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..331fac6 --- /dev/null +++ b/index.html @@ -0,0 +1,34 @@ + + + + + + + + + Tetris + + + +
+ +
+

Tetris

+

Score: 0

+
+
➡️ Cursor derecha
+
⬅️ Cursor izquierda
+
⬇️ Cursor abajo
+
🔄 Barra espaciadora
+
1️⃣ Ventana debug
+
+
Esc - Salir partida
+ +
+
+ + + + + + \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..f1e0636 --- /dev/null +++ b/style.css @@ -0,0 +1,67 @@ +* { + box-sizing: border-box; + min-width: 0; +} + +body { + margin: 0; + padding: 0; + background: linear-gradient(to bottom right, #0f2027, #203a43, #2c5364); + min-height: 100vh; + min-width: 100vw; + color: white; + font-family: "Press Start 2P", cursive; +} + +#gui { + padding-top: 2%; + width: fit-content; + margin: auto; + display: flex; + flex-direction: row; + gap: 2rem; +} + +#tablero { + border: 4px solid white; + background-color: #282829; + height: 80vh; + width: 400px; +} + +#marcador { + display: flex; + flex-direction: column; + gap: 1rem; +} + +textarea { + position: absolute; + top: 2%; + left: 1rem; + background-color: transparent; + color: white; + display: none; +} + +#leyendaTeclas { + font-size: 10px; +} + +button { + font-size: 16px; + background-color: #4caf50; + color: white; + border: none; + padding: 10px 20px; + text-align: center; + text-decoration: none; + display: inline-block; + margin: 4px 2px; + cursor: pointer; + border-radius: 4px; +} + +button:hover { + background-color: #45a049; +}