Cómo Crear un Juego Clásico de Snake con JavaScript, HTML y CSS: Tutorial Paso a Paso
¡Bienvenido a este tutorial JavaScript en el que aprenderás a crear un clásico juego de Snake! Este proyecto es perfecto para desarrolladores principiantes interesados en la programación frontend y el desarrollo web para principiantes. Te guiaré paso a paso para que puedas entender la lógica del juego, controlar la serpiente, generar comida, detectar colisiones y actualizar la puntuación. Además, te mostraré cómo organizar tu código JavaScript interactivo para que sea claro y funcional.
Índice
- Configuración básica del proyecto
- Estructura HTML para el juego Snake
- Estilos CSS para un diseño simple y funcional
- Lógica JavaScript: Control de la serpiente
- Generación de comida y detección de colisiones
- Actualizar la puntuación en pantalla
- Mejoras y funcionalidades extra sugeridas
- Conclusión y buenas prácticas
Configuración básica del proyecto
Para comenzar, crea una carpeta para tu proyecto (por ejemplo, snake-game
). Dentro, crea tres archivos:
index.html
: tu archivo HTML principalstyles.css
: donde pondremos los estilosscript.js
: para la lógica del juego con JavaScript
Tu estructura quedará así:
1 2 3 4 5 |
snake-game/ ├── index.html ├── styles.css └── script.js |
Usaremos un lienzo (<canvas>
) para dibujar el juego, ideal para gráficos dinámicos y juegos simples.
Estructura HTML para el juego Snake
Vamos a crear el archivo index.html
con un lienzo y un área para mostrar la puntuación:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Juego Snake con JavaScript</title> <link rel="stylesheet" href="styles.css" /> </head> <body> <h1>Juego clásico de Snake</h1> <p>Puntuación: <span id="score">0</span></p> <canvas id="gameCanvas" width="400" height="400"></canvas> <script src="script.js"></script> </body> </html> |
Explicación:
<canvas>
es el área donde se dibujará el juego.- El elemento
<span id="score">
mostrará la puntuación actual. - Vinculamos el CSS y el JavaScript para mantener código organizado.
Estilos CSS para un diseño simple y funcional
Abre styles.css
y añade estilos para centrar y diseñar el juego:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
body { font-family: Arial, sans-serif; text-align: center; background-color: #f0f0f0; margin: 0; padding: 20px; } h1 { color: #333; } #gameCanvas { background-color: #000; display: block; margin: 0 auto; border: 2px solid #555; } p { font-size: 20px; color: #555; } |
¿Por qué estas reglas?
- Fondo claro y lienzo oscuro para hacer el Snake visible.
- El canvas centrado mejora la UX.
- Texto con buena legibilidad.
Lógica JavaScript: Control de la serpiente
Ahora empieza la parte clave: la lógica del juego con JavaScript interactivo.
Abramos script.js
y define las variables y funciones básicas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
// Seleccionamos el canvas y configuramos contexto 2D const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); // Definimos el tamaño de cada segmento de la serpiente const box = 20; // 20x20px por segmento // Definir la serpiente como un array de objetos con x,y let snake = []; snake[0] = { x: 9 * box, y: 10 * box }; // Dirección inicial: derecha let direction = 'RIGHT'; // Escuchar eventos de teclado para mover la serpiente window.addEventListener('keydown', changeDirection); function changeDirection(event) { const key = event.keyCode; if (key === 37 && direction !== 'RIGHT') { direction = 'LEFT'; } else if (key === 38 && direction !== 'DOWN') { direction = 'UP'; } else if (key === 39 && direction !== 'LEFT') { direction = 'RIGHT'; } else if (key === 40 && direction !== 'UP') { direction = 'DOWN'; } } // Dibuja la serpiente en el canvas function drawSnake() { for (let i = 0; i < snake.length; i++) { ctx.fillStyle = (i === 0) ? 'lime' : 'white'; // cabeza verde ctx.fillRect(snake[i].x, snake[i].y, box, box); ctx.strokeStyle = 'black'; ctx.strokeRect(snake[i].x, snake[i].y, box, box); } } // Función principal del juego function game() { ctx.clearRect(0, 0, canvas.width, canvas.height); // Limpiar canvas drawSnake(); // Definir posición nueva según dirección let snakeX = snake[0].x; let snakeY = snake[0].y; if (direction === 'LEFT') snakeX -= box; else if (direction === 'UP') snakeY -= box; else if (direction === 'RIGHT') snakeX += box; else if (direction === 'DOWN') snakeY += box; // A partir de aquí añadiremos comida, colisiones, etc. // Añadimos nueva cabeza al inicio del array snake.pop(); // quitamos último segmento (avanza sin crecer momentáneamente) snake.unshift({ x: snakeX, y: snakeY }); } // Ejecutar juego 100ms let gameInterval = setInterval(game, 100); |
Explicación paso a paso:
- Definimos la serpiente como un array de bloques con coordenadas
x,y
. - Escuchamos las teclas para cambiar la dirección, evitando que el Snake se mueva hacia atrás.
- En cada frame (cada 100ms), movemos la serpiente en la dirección actual.
drawSnake
dibuja cada segmento y la cabeza en verde.
Consejo: Usa constante box
para mantener la cuadrícula y mover la serpiente segmentada.
Generación de comida y detección de colisiones
Siguiente funcionalidad: generar comida aleatoria y detectar si la serpiente la come, además de controlar colisiones con las paredes y con ella misma.
Extiende tu código script.js
así:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
// Generar comida en una posición aleatoria (dentro del mapa 20x20 caja de 20px) let food = { x: Math.floor(Math.random() * 20) * box, y: Math.floor(Math.random() * 20) * box }; // Dibujar la comida function drawFood() { ctx.fillStyle = 'red'; ctx.fillRect(food.x, food.y, box, box); } // Función que detecta si la serpiente colisiona consigo misma function collision(head, array) { for (let i = 0; i < array.length; i++) { if (head.x === array[i].x && head.y === array[i].y) { return true; } } return false; } // Actualizamos función game() function game() { ctx.clearRect(0, 0, canvas.width, canvas.height); drawSnake(); drawFood(); // Cabeza let snakeX = snake[0].x; let snakeY = snake[0].y; if (direction === 'LEFT') snakeX -= box; else if (direction === 'UP') snakeY -= box; else if (direction === 'RIGHT') snakeX += box; else if (direction === 'DOWN') snakeY += box; // Si la serpiente come la comida if (snakeX === food.x && snakeY === food.y) { score += 1; document.getElementById('score').innerText = score; // Genera nueva comida food = { x: Math.floor(Math.random() * 20) * box, y: Math.floor(Math.random() * 20) * box }; // No podemos quitar el último segmento para que crezca } else { // Eliminar último segmento (para que avance sin crecer si no come) snake.pop(); } // Nueva cabeza let newHead = { x: snakeX, y: snakeY }; // Si colisiona con paredes o consigo misma se termina el juego if ( snakeX < 0 || snakeX >= canvas.width || snakeY < 0 || snakeY >= canvas.height || collision(newHead, snake) ) { clearInterval(gameInterval); alert('¡Fin del juego! Tu puntuación fue: ' + score); return; } snake.unshift(newHead); } // Iniciar puntuación let score = 0; // Reiniciar juego para que arranque correctamente let gameInterval = setInterval(game, 100); |
Explicación:
food
se genera en coordenadas que encajan con la cuadrícula.- Si la cabeza toca la comida, aumentamos la puntuación y generamos nueva comida.
- La serpiente crece porque no quitamos su cola.
- Validamos colisiones con las paredes (bordes del canvas) y con sí misma; si hay choque, el juego termina.
Actualizar la puntuación en pantalla
La puntuación se muestra en el <span id="score">
y se actualiza cada vez que la serpiente come. Esto ya está implementado dentro del bloque anterior con esta línea:
1 2 |
document.getElementById('score').innerText = score; |
Esta simple línea refresca el marcador en tiempo real, fundamental para la experiencia del jugador.
Mejoras y funcionalidades extra sugeridas
¡Genial! Ya tienes tu juego Snake básico funcionando. Aquí algunos consejos y funcionalidades que podrías implementar para profundizar tu aprendizaje:
1. Añadir botones para reiniciar o pausar
Crea botones para que el usuario pueda reiniciar la partida sin recargar la página o pausar el juego.
2. Variar la velocidad según la puntuación
Para un reto mayor, aumenta la velocidad (setInterval
) según el score.
3. Implementar niveles o paredes fijas
Agrega obstáculos que la serpiente debe evitar.
4. Mejorar el diseño y animaciones
Usa imágenes, gradientes o sombras para modernizar la estética.
5. Guardar los mejores puntajes
Usa localStorage
para guardar récords del jugador y mostrarlos.
6. Soporte para versiones móviles
Detecta y adapta controles táctiles para smartphone.
Conclusión y buenas prácticas
Crear este juego clásico Snake con JavaScript, HTML y CSS es un excelente ejercicio para practicar conceptos esenciales de desarrollo web para principiantes y programación frontend.
Recapitulando:
- Configuramos los archivos básicos con
<canvas>
para gráficos dinámicos. - Implementamos el control de la serpiente mediante eventos de teclado.
- Generamos comida aleatoria y detectamos colisiones para gestionar el estado del juego.
- Actualizamos la puntuación en pantalla para mostrar progreso.
Buenas prácticas recomendadas:
- Usa variables constantes para controlar dimensiones y velocidades.
- Separa la lógica en funciones pequeñas y comentadas para mejorar mantenimiento.
- Valida siempre entradas del usuario para evitar comportamientos inesperados.
- Prueba el juego en diferentes navegadores para garantizar compatibilidad.
Ahora que sabes cómo hacer tu propio juego Snake con código JavaScript interactivo, te invito a experimentar con nuevas funcionalidades y perfeccionar tu estilo de programación. ¡Diviértete creando y aprendiendo!
Si te gustó este tutorial JavaScript, no olvides compartirlo y seguir practicando. ¡El desarrollo web para principiantes empieza con proyectos como este!