🐍 Serpiente en HTML puro + JS: ¡paso a paso y con memes!
¿Alguna vez has soñado con escribir tu propio juego? ¿Y qué hay de los clásicos? Serpientes? 😎 Hoy vamos a crear un juego retro de verdad en el navegador, paso a paso. Sin bibliotecas, sin marcos, solo HTML, CSS y JavaScript.
⚠️ Spoiler: no solo lanzarás una serpiente, sino que entenderás cómo funciona.
Y si de repente te parece que es difícil, tranquilidad, solo tranquilidad, lo explicaremos todo con memes y ejemplos. ¡Vamos! 🚀

✨ Demo del proyecto | 📂 Descargar el código fuente en GitHub
🤖 En la aplicación Kodik ¡Puedes aprender HTML, CSS y JavaScript, así como muchos otros cursos para comenzar tu viaje en el desarrollo web! 🌱
📦 Paso 1: HTML — creamos la base del juego
HTML es el esqueleto. En él colocamos:
canvas— nuestro lienzo, en el que dibujaremos una serpiente y comida;divcon botones para iniciar y finalizar el juego;contador de puntos.
<canvas id="game" width="320" height="320"></canvas>🎨 Paso 2: CSS: el estilo sin el que sería aburrido
Un poco de magia de estilos:
fondo negro
lienzo con marco y bordes redondeados
adaptación a dispositivos móviles (touch-action)
Los botones, los títulos, las pantallas de inicio y de finalización también están diseñados para que el juego se vea agradable.
🧠 Paso 3: JavaScript es el cerebro de toda la serpiente 🧬
Ahora analicemos en detalle todo el código del juego.
1. Inicialización de elementos:
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");canvas — obtenemos acceso al elemento de lienzo. ctx es lo que usaremos para dibujar.
También declaramos las variables: tamaño de la celda, dirección de la serpiente, puntos, velocidad y estado del juego.
const scale = 20;
const rows = canvas.height / scale;
const columns = canvas.width / scale;
let direction = { x: 1, y: 0 };
let nextDirection = { x: 1, y: 0 };
let speed = 250;
let score = 0;2. Clase Snake — la serpiente misma:
class Snake {
constructor() {
this.body = [
{ x: 5, y: 5 },
{ x: 4, y: 5 },
];
}
update() {
const head = { ...this.body[0] };
head.x += direction.x;
head.y += direction.y;
this.body.unshift(head);
if (head.x === fruit.x && head.y === fruit.y) {
score++;
if (speed > 80) speed -= 5;
placeFruit();
} else {
this.body.pop();
}
}
draw() {
this.body.forEach((segment, i) => {
ctx.fillStyle = i === 0 ? "#58a6ff" : "#3fb950";
ctx.beginPath();
ctx.roundRect(
segment.x * scale + 2,
segment.y * scale + 2,
scale - 4,
scale - 4,
6
);
ctx.fill();
});
}
checkCollision() {
const [head, ...body] = this.body;
return (
head.x < 0 ||
head.x >= columns ||
head.y < 0 ||
head.y >= rows ||
body.some((s) => s.x === head.x && s.y === head.y)
);
}
}Explicación:
update()— movemos la serpiente y comprobamos si se ha comido la fruta;draw()— dibujamos cada segmento;checkCollision()— comprobación de colisiones con los límites o consigo mismo.
3. Comida (fruta):
function placeFruit() {
fruit = {
x: Math.floor(Math.random() * columns),
y: Math.floor(Math.random() * rows),
};
if (snake.body.some((s) => s.x === fruit.x && s.y === fruit.y)) {
placeFruit();
}
}La comida se coloca al azar. Si cae sobre una serpiente, se genera de nuevo.
4. Ciclo de juego:
function gameLoop(time = 0) {
if (!playing) return;
const delta = time - lastTime;
if (delta > speed) {
direction = nextDirection;
ctx.clearRect(0, 0, canvas.width, canvas.height);
snake.update();
if (snake.checkCollision()) {
endGame();
return;
}
drawFruit();
snake.draw();
lastTime = time;
}
requestAnimationFrame(gameLoop);
}Cada «cuadro»:
limpiamos el lienzo
mover la serpiente
comprobamos la muerte
dibujamos comida y serpiente
5. Administración:
Teclado:
window.addEventListener("keydown", (e) => {
if (e.key === "ArrowUp" && direction.y !== 1) nextDirection = { x: 0, y: -1 };
if (e.key === "ArrowDown" && direction.y !== -1) nextDirection = { x: 0, y: 1 };
if (e.key === "ArrowLeft" && direction.x !== 1) nextDirection = { x: -1, y: 0 };
if (e.key === "ArrowRight" && direction.x !== -1) nextDirection = { x: 1, y: 0 };
});Deslizamientos:
canvas.addEventListener("touchstart", (e) => { ... });
canvas.addEventListener("touchend", (e) => { ... });💀 Fin del juego:
function endGame() {
playing = false;
canvas.style.display = "none";
scoreDisplay.style.display = "none";
gameOverScreen.style.display = "flex";
finalScore.textContent = `You scored ${score} points`;
}✅ Conclusión: te has convertido en un maestro de las serpientes 🐍
No solo has escrito el código, sino que has entendido cómo funciona la lógica del juego. ¡Es un gran paso!
¿Quieres aprender más? Entra en Kodik — hay un montón de práctica, explicaciones en un lenguaje sencillo y tareas divertidas.
