Version Beta

This commit is contained in:
Marklogo 2024-03-09 12:14:14 +01:00
commit a978d0b7a5
5 changed files with 385 additions and 0 deletions

0
README.md Normal file
View File

BIN
assets/Tetris.mp3 Normal file

Binary file not shown.

284
game.js Normal file
View File

@ -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`;
}

34
index.html Normal file
View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<title>Tetris</title>
</head>
<body>
<div id="gui">
<canvas id="tablero" width="200" height="400"></canvas>
<div id="marcador">
<h2>Tetris</h2>
<p>Score: <span id="score">0</span> </p>
<div id="leyendaTeclas">
<div><span style="font-size: 24px;">➡️</span> Cursor derecha</div>
<div><span style="font-size: 24px;">⬅️</span> Cursor izquierda</div>
<div><span style="font-size: 24px;">⬇️</span> Cursor abajo</div>
<div><span style="font-size: 24px;">🔄</span> Barra espaciadora</div>
<div><span style="font-size: 24px;">1</span> Ventana debug</div>
</div>
<div style="font-size: 8px;">Esc - Salir partida</div>
<button id="startButton" onclick="iniciarPartida()">Start</button>
</div>
</div>
<textarea id="debug" cols="30" rows="10"></textarea>
<audio id="musica" src="./assets/Tetris.mp3" loop></audio>
<script src="game.js"></script>
</body>
</html>

67
style.css Normal file
View File

@ -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;
}