En este ejemplo se muestra cómo construir un juego básico de Tetris utilizando HTML, CSS y JavaScript. Este código se basa en el elemento <canvas> para renderizar el tablero y las piezas, mientras que el estilo se logra a través de CSS y la lógica del juego (aunque simplificada) se implementa en JavaScript.
El proyecto consta de tres archivos principales:
A continuación se presenta el código HTML que define la estructura básica del juego y enlaza los archivos de estilo y script:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tetris</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<canvas id="tetris" width="300" height="600"></canvas>
<script src="tetris.js"></script>
</body>
</html>
El estilo básico del juego se logra con CSS, centrando el canvas y aplicando un fondo oscuro y un borde visual:
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: #000;
margin: 0;
}
canvas {
border: 1px solid #fff;
}
El siguiente script JavaScript contiene la lógica base para el juego. Define el canvas, configura el contexto, dibuja el tablero y agrega una pieza inicial en el tablero. Se incluyen funciones para dibujar el tablero y agregar piezas. Este es el punto de partida para extender el juego con movimientos, rotaciones y manejo de colisiones.
// Configuración del canvas
const canvas = document.getElementById('tetris');
const context = canvas.getContext('2d');
context.scale(30, 30); // Escala para facilitar el dibujo
// Dimensiones del tablero (10 columnas x 20 filas)
const COLS = 10;
const ROWS = 20;
// Crear la matriz del tablero
function createBoard() {
const board = [];
for (let y = 0; y < ROWS; y++) {
board.push(new Array(COLS).fill(0));
}
return board;
}
let board = createBoard();
// Definición de colores para las piezas (los colores asociados a cada pieza)
const colors = [
null, // Índice 0: sin color
'#FF0D72', // Pieza I
'#0DC2FF', // Pieza J
'#0DFF72', // Pieza L
'#F538FF', // Pieza O
'#FF8E0D', // Pieza S
'#FFE138', // Pieza T
'#3877FF' // Pieza Z
];
// Ejemplo de piezas de Tetris representadas en matrices
const pieces = {
'T': [
[0, 1, 0],
[1, 1, 1],
[0, 0, 0]
],
'O': [
[2, 2],
[2, 2]
],
'L': [
[0, 0, 3],
[3, 3, 3],
[0, 0, 0]
],
// Se pueden agregar más piezas (I, J, S, Z) de forma similar...
};
// Función para dibujar el tablero
function drawBoard() {
context.fillStyle = '#000';
context.fillRect(0, 0, canvas.width, canvas.height);
for (let y = 0; y < board.length; y++) {
for (let x = 0; x < board[y].length; x++) {
if (board[y][x] !== 0) {
context.fillStyle = colors[board[y][x]];
context.fillRect(x, y, 1, 1);
}
context.strokeStyle = 'gray';
context.strokeRect(x, y, 1, 1);
}
}
}
// Función para agregar una pieza al tablero
function merge(piece, pos) {
piece.matrix.forEach((row, y) => {
row.forEach((value, x) => {
if (value !== 0) {
board[y + pos.y][x + pos.x] = value;
}
});
});
}
// Función para crear una nueva pieza aleatoria
function createPiece(type) {
return pieces[type] ? pieces[type] : pieces['T']; // Valor por defecto 'T'
}
// Crear un objeto de pieza en juego
let currentPiece = {
matrix: createPiece('T'),
pos: {x: 3, y: 0}
};
// Función para dibujar la pieza en el canvas
function drawPiece(piece) {
piece.matrix.forEach((row, y) => {
row.forEach((value, x) => {
if (value !== 0) {
context.fillStyle = colors[value];
context.fillRect(piece.pos.x + x, piece.pos.y + y, 1, 1);
}
});
});
}
// Actualizar el juego: dibujar tablero y pieza actual
function update() {
drawBoard();
drawPiece(currentPiece);
}
// Configuración de la actualización del juego (se actualiza aproximadamente 2 veces por segundo)
setInterval(update, 500);
// Función para mover la pieza
function movePiece(offsetX, offsetY) {
currentPiece.pos.x += offsetX;
currentPiece.pos.y += offsetY;
// Aquí se debe incluir validación de colisiones
update();
}
// Ejemplo de movimiento: mover la pieza hacia abajo cada 0.5 segundos
// Además, se podría añadir control de eventos de teclado para mover y rotar la pieza.
// Escuchar eventos del teclado para el control del juego
document.addEventListener('keydown', event => {
if (event.key === 'ArrowLeft') {
movePiece(-1, 0);
} else if (event.key === 'ArrowRight') {
movePiece(1, 0);
} else if (event.key === 'ArrowDown') {
movePiece(0, 1);
}
});
| Archivo | Función Principal | Descripción |
|---|---|---|
| index.html | Estructura y enlace | Contiene la estructura básica HTML y el canvas para el juego. |
| styles.css | Estilos visuales | Define el fondo, centrado y borde del canvas. |
| tetris.js | Lógica y dibujo | Incluye la lógica para crear el tablero, generar y dibujar piezas, y actualizar el juego. |
El objeto canvas se usa para dibujar gráficos de forma dinámica. Con JavaScript se obtiene el contexto 2D a través de getContext('2d'), lo que permite escalar los dibujos y trabajar con cada celda del tablero. Se ha utilizado el método scale(30, 30) para que cada unidad del sistema de coordenadas represente una celda de 30 píxeles.
Las piezas se definen como matrices en JavaScript (por ejemplo, la pieza T o la pieza O). Cada número dentro de la matriz representa la existencia de un bloque y se asocia con un color específico. Este sistema facilita la extensión, para incluir nuevas piezas siguiendo la misma estructura.
La función principal de actualización del juego se realiza en intervalos regulares usando setInterval. Esto refresca el canvas y redibuja tanto el tablero como la pieza actual. Se recomienda ampliar este mecanismo para incluir validaciones de colisiones y detección de líneas completas que se deben eliminar, características esenciales de un juego de Tetris completo.
Para crear una experiencia más completa, se pueden implementar funcionalidades adicionales tales como: