Version Beta
This commit is contained in:
commit
a978d0b7a5
BIN
assets/Tetris.mp3
Normal file
BIN
assets/Tetris.mp3
Normal file
Binary file not shown.
284
game.js
Normal file
284
game.js
Normal 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
34
index.html
Normal 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
67
style.css
Normal 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;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user