Se trata de un juego de «esquiva los asteroides». Controlas una nave espacial en la parte inferior de la pantalla y debes evitar que los asteroides que caen desde arriba te golpeen. Tu puntuación aumenta cada segundo que sobrevives.
Características del Juego:
- Gráficos simples: Utiliza el elemento
<canvas>
de HTML5 para dibujar los elementos del juego. - Controles: Usa las flechas izquierda y derecha del teclado para mover la nave.
- Puntuación: Ganas puntos por cada segundo que permaneces en el juego.
- Game Over: El juego termina cuando un asteroide choca contra tu nave.
- Reinicio: Puedes reiniciar el juego con un botón después de perder.

Código Completo
Solo tienes que copiar todo este código, pegarlo en un archivo de texto, guardarlo con la extensión .html
(por ejemplo, juego.html
) y abrirlo en tu navegador web.
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Esquiva los Asteroides</title>
<style> /* Estilos básicos para que se vea bien */ body { background-color: #000; color: #fff; font-family: 'Courier New', Courier, monospace; display: flex; flex-direction: column; justify-content: center; align-items: center; height: 100vh; margin: 0; overflow: hidden; /* Evita barras de desplazamiento */ } h1 { margin-bottom: 20px; color: #00ff00; text-shadow: 0 0 10px #00ff00; } #game-container { position: relative; border: 2px solid #fff; box-shadow: 0 0 20px #00ff00; } #gameCanvas { display: block; background-color: #111; } #score { position: absolute; top: 10px; left: 10px; font-size: 24px; color: #fff; } #game-over { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; display: none; /* Oculto por defecto */ } #game-over h2 { font-size: 48px; color: #ff0000; margin-bottom: 20px; } #restart-button { padding: 10px 20px; font-size: 20px; cursor: pointer; background-color: #00ff00; color: #000; border: none; border-radius: 5px; transition: background-color 0.3s; } #restart-button:hover { background-color: #fff; } </style>
</head> <body> <h1>Esquiva los Asteroides</h1> <div id="game-container"> <canvas id="gameCanvas" width="600" height="400"></canvas> <div id="score">Puntuación: 0</div> <div id="game-over"> <h2>GAME OVER</h2> <button id="restart-button">Reiniciar</button> </div> </div>
<script> // --- CONFIGURACIÓN INICIAL --- const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); const scoreElement = document.getElementById('score'); const gameOverElement = document.getElementById('game-over'); const restartButton = document.getElementById('restart-button'); // --- VARIABLES DEL JUEGO --- let score = 0; let gameIsOver = false; let asteroidSpawnTimer = 0; let asteroidSpawnInterval = 60; // Spawn cada 60 frames (aprox. 1 segundo) // --- OBJETO JUGADOR --- const player = { x: canvas.width / 2 - 25, y: canvas.height - 60, width: 50, height: 50, speed: 7, color: '#00ff00', draw: function() { ctx.fillStyle = this.color; // Dibujamos una forma simple de nave ctx.beginPath(); ctx.moveTo(this.x + this.width / 2, this.y); ctx.lineTo(this.x, this.y + this.height); ctx.lineTo(this.x + this.width, this.y + this.height); ctx.closePath(); ctx.fill(); } }; // --- ARRAY DE ASTEROIDES --- let asteroids = []; // --- CLASE ASTEROIDE --- class Asteroid { constructor() { this.width = 30 + Math.random() * 40; // Tamaño aleatorio this.height = this.width; this.x = Math.random() * (canvas.width - this.width); this.y = -this.height; // Empieza fuera de la pantalla this.speed = 2 + Math.random() * 3; // Velocidad aleatoria this.color = `hsl(${Math.random() * 60 + 15}, 100%, 50%)`; // Color entre naranja y amarillo } draw() { ctx.fillStyle = this.color; ctx.fillRect(this.x, this.y, this.width, this.height); } update() { this.y += this.speed; } } // --- CONTROL DE TECLADO --- const keys = {}; document.addEventListener('keydown', (e) => { keys[e.key] = true; }); document.addEventListener('keyup', (e) => { keys[e.key] = false; }); // --- LÓGICA DEL JUEGO --- function handlePlayerInput() { if (keys['ArrowLeft'] && player.x > 0) { player.x -= player.speed; } if (keys['ArrowRight'] && player.x < canvas.width - player.width) { player.x += player.speed; } } function spawnAsteroid() { asteroidSpawnTimer++; if (asteroidSpawnTimer >= asteroidSpawnInterval) { asteroids.push(new Asteroid()); asteroidSpawnTimer = 0; // Aumentar dificultad gradualmente if (asteroidSpawnInterval > 20) { asteroidSpawnInterval -= 0.5; } } } function checkCollisions() { for (let asteroid of asteroids) { if ( player.x < asteroid.x + asteroid.width && player.x + player.width > asteroid.x && player.y < asteroid.y + asteroid.height && player.y + player.height > asteroid.y ) { endGame(); } } } function updateScore() { // La puntuación se actualiza en un setInterval separado para mayor precisión } function endGame() { gameIsOver = true; gameOverElement.style.display = 'block'; } function resetGame() { score = 0; scoreElement.textContent = `Puntuación: ${score}`; gameIsOver = false; gameOverElement.style.display = 'none'; player.x = canvas.width / 2 - 25; asteroids = []; asteroidSpawnTimer = 0; asteroidSpawnInterval = 60; gameLoop(); // Reiniciar el bucle del juego } // --- BUCLE PRINCIPAL DEL JUEGO --- function gameLoop() { if (gameIsOver) { return; // Detener el bucle si el juego ha terminado } // 1. LIMPIAR CANVAS ctx.clearRect(0, 0, canvas.width, canvas.height); // 2. ACTUALIZAR ELEMENTOS handlePlayerInput(); spawnAsteroid(); // Actualizar y filtrar asteroides que salen de la pantalla asteroids = asteroids.filter(asteroid => { asteroid.update(); return asteroid.y < canvas.height; // Mantener solo los que están visibles }); checkCollisions(); // 3. DIBUJAR ELEMENTOS player.draw(); asteroids.forEach(asteroid => asteroid.draw()); // 4. VOLVER A LLAMAR AL BUCLE requestAnimationFrame(gameLoop); } // --- INICIALIZACIÓN --- restartButton.addEventListener('click', resetGame); // Iniciar el bucle del juego gameLoop(); // Intervalo para aumentar la puntuación setInterval(() => { if (!gameIsOver) { score++; scoreElement.textContent = `Puntuación: ${score}`; } }, 1000); // Cada segundo </script>
</body> </html>
Cómo Funciona
- HTML (
<body>
): Define la estructura visible de la página.- Un
<h1>
para el título. - Un
<div>
(#game-container
) que envuelve el área de juego. - Un
<canvas>
que es el lienzo donde se dibujará el juego. - Un
<div>
para mostrar la puntuación (#score
). - Un
<div>
(#game-over
) que contiene el mensaje de fin de juego y el botón de reinicio. Está oculto por defecto.
- Un
- CSS (
<style>
): Se encarga de la apariencia.- Centra el contenido en la página.
- Le da un fondo negro y un estilo «futurista» con colores verdes y sombras.
- Posiciona la puntuación y la pantalla de «Game Over» sobre el canvas.
- JavaScript (
<script>
): Es el cerebro del juego.- Configuración: Obtiene las referencias a los elementos del HTML y define variables iniciales.
- Objeto
player
: Define las propiedades de la nave (posición, tamaño, color) y un métododraw()
para dibujarla. - Clase
Asteroid
: Es un molde para crear asteroides. Cada asteroide tendrá un tamaño, posición y velocidad aleatorios. - Control de Teclado: Escucha los eventos
keydown
ykeyup
para saber cuándo el jugador presiona las flechas. gameLoop()
: Es la función más importante. Se ejecuta constantemente usandorequestAnimationFrame
para crear la ilusión de movimiento. En cada «fotograma»:- Limpia el canvas.
- Actualiza la posición del jugador y los asteroides.
- Comprueba si hay colisiones.
- Dibuja todos los elementos en sus nuevas posiciones.
- Se llama a sí misma para el siguiente fotograma.
resetGame()
: Restablece todas las variables a su estado inicial para poder empezar de nuevo.
Posibles Mejoras (¡para que practiques!)
- Vidas: En lugar de que el juego termine en el primer golpe, dale al jugador 3 vidas.
- Disparar: Permite que la nave dispare láseres para destruir asteroides.
- Sonidos: Añade efectos de sonido para los disparos, explosiones y la música de fondo.
- Pantalla de Inicio: Crea una pantalla de bienvenida antes de que comience el juego.
- Mejores Gráficos: Dibuja sprites más detallados en lugar de simples formas geométricas.
–