0% found this document useful (0 votes)
18 views5 pages

Juego de Serpiente en JavaScript

The document is an HTML file that implements a simple Snake game using JavaScript and the HTML5 canvas. It includes game controls, a scoring system, and a user interface styled with CSS. The game allows players to control the snake, eat food to grow, and keeps track of the best score using local storage.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views5 pages

Juego de Serpiente en JavaScript

The document is an HTML file that implements a simple Snake game using JavaScript and the HTML5 canvas. It includes game controls, a scoring system, and a user interface styled with CSS. The game allows players to control the snake, eat food to grow, and keeps track of the best score using local storage.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

<!

DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<title>Snake JS — Duver</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
:root {
--bg: #0f1226;
--grid: #1c2140;
--snake: #34d399; /* Verde menta */
--snake-head: #10b981;
--food: #f59e0b; /* Ámbar */
--text: #e5e7eb;
--accent: #60a5fa;
}
* { box-sizing: border-box; }
body {
margin: 0; min-height: 100vh; display: grid; place-items: center;
background: radial-gradient(1200px 600px at 30% -10%, #1a1f3b, transparent),
var(--bg);
color: var(--text); font-family: ui-sans-serif, system-ui, -apple-system,
Segoe UI, Roboto, Arial;
}
.wrap { display: grid; gap: 14px; justify-items: center; }
h1 { margin: 0; font-size: 20px; font-weight: 700; letter-spacing: .3px; color:
var(--accent); }
canvas {
background: repeating-linear-gradient(0deg, var(--grid), var(--grid) 20px,
transparent 20px, transparent 40px),
repeating-linear-gradient(90deg, var(--grid), var(--grid) 20px,
transparent 20px, transparent 40px),
#0b0f24;
box-shadow: 0 8px 30px rgba(0,0,0,.55), 0 0 0 1px rgba(255,255,255,.05)
inset;
border-radius: 10px;
}
.hud { display: flex; gap: 16px; align-items: center; font-size: 14px; }
.pill { padding: 6px 10px; border-radius: 999px; background:
rgba(96,165,250,.12); border: 1px solid rgba(96,165,250,.25); }
.keys { opacity: .8; font-size: 12px; }
button {
background: #1f2937; color: var(--text); border: 1px solid #374151; border-
radius: 8px;
padding: 8px 12px; cursor: pointer;
}
button:hover { background: #2b3650; }
@media (max-width: 520px) {
canvas { width: 300px; height: 300px; }
}
</style>
</head>
<body>
<div class="wrap">
<h1>Snake JS</h1>
<canvas id="game" width="400" height="400" aria-label="Tablero del juego"
role="img"></canvas>
<div class="hud">
<div class="pill">Puntos: <span id="score">0</span></div>
<div class="pill">Récord: <span id="best">0</span></div>
<div class="keys">Controles: Flechas/WASD · P = Pausa · R = Reiniciar</div>
<button id="btn">Pausa</button>
</div>
</div>

<script>
// Configuración del tablero
const canvas = [Link]('game');
const ctx = [Link]('2d');
const SIZE = 20; // tamaño de cada celda (px)
const CELLS = [Link] / SIZE; // 400/20 = 20 celdas por lado

// HUD
const scoreEl = [Link]('score');
const bestEl = [Link]('best');
const btn = [Link]('btn');

// Estado del juego


let snake, dir, nextDir, food, score, best, speed, tickId, paused, gameOver;

function init() {
snake = [{ x: 10, y: 10 }]; // cabeza en el centro
dir = { x: 1, y: 0 }; // moviendo a la derecha
nextDir = { ...dir };
score = 0;
speed = 120; // ms por tick (menor = más rápido)
paused = false;
gameOver = false;
[Link] = '0';
best = Number([Link]('snake_best') || 0);
[Link] = best;
placeFood();
clearInterval(tickId);
tickId = setInterval(loop, speed);
draw();
}

function placeFood() {
// Coloca la comida en una celda libre
while (true) {
const f = { x: rand(0, CELLS - 1), y: rand(0, CELLS - 1) };
if (![Link](s => s.x === f.x && s.y === f.y)) { food = f; break; }
}
}

function rand(min, max) {


return [Link]([Link]() * (max - min + 1)) + min;
}

function loop() {
if (paused || gameOver) return;

// Actualiza dirección sin permitir giro de 180°


if ((nextDir.x !== -dir.x || nextDir.y !== -dir.y)) dir = nextDir;

const head = { x: snake[0].x + dir.x, y: snake[0].y + dir.y };

// Colisiones con muro


if (head.x < 0 || head.y < 0 || head.x >= CELLS || head.y >= CELLS) {
return end();
}
// Colisión consigo misma
if ([Link](s => s.x === head.x && s.y === head.y)) {
return end();
}

[Link](head); // mueve la cabeza

// Comer
if (head.x === food.x && head.y === food.y) {
score++;
[Link] = score;
if (score % 5 === 0 && speed > 60) { // aumenta dificultad
speed -= 5;
clearInterval(tickId);
tickId = setInterval(loop, speed);
}
placeFood();
} else {
[Link](); // avanza (quita cola) si no come
}

draw();
}

function end() {
gameOver = true;
if (score > best) {
best = score;
[Link]('snake_best', best);
}
[Link] = best;
// Mensaje de fin de juego
draw();
[Link] = 'rgba(0,0,0,.6)';
[Link](0, 0, [Link], [Link]);
[Link] = '#ffffff';
[Link] = 'bold 22px Segoe UI, Arial';
[Link] = 'center';
[Link]('¡Juego terminado!', [Link] / 2, [Link] / 2 - 10);
[Link] = '16px Segoe UI, Arial';
[Link]('Pulsa R para reiniciar', [Link] / 2, [Link] / 2 +
18);
}

function draw() {
// Fondo (el grid está en el CSS)
[Link](0, 0, [Link], [Link]);

// Comida
drawCell(food.x, food.y, '#00000022'); // sombra sutil
drawRoundedCell(food.x, food.y, 6, getCss('--food'));

// Serpiente
[Link]((seg, i) => {
const color = i === 0 ? getCss('--snake-head') : getCss('--snake');
drawRoundedCell(seg.x, seg.y, 4, color);
});
}

function drawCell(x, y, color) {


[Link] = color;
[Link](x * SIZE, y * SIZE, SIZE, SIZE);
}

function drawRoundedCell(x, y, r, color) {


const px = x * SIZE, py = y * SIZE, w = SIZE, h = SIZE;
[Link] = color;
[Link]();
[Link](px + r, py);
[Link](px + w, py, px + w, py + h, r);
[Link](px + w, py + h, px, py + h, r);
[Link](px, py + h, px, py, r);
[Link](px, py, px + w, py, r);
[Link]();
[Link]();
}

function getCss(varName) {
return
getComputedStyle([Link]).getPropertyValue(varName).trim();
}

// Controles
[Link]('keydown', (e) => {
const k = [Link]();
const map = {
arrowup: { x: 0, y: -1 }, w: { x: 0, y: -1 },
arrowdown: { x: 0, y: 1 }, s: { x: 0, y: 1 },
arrowleft: { x: -1, y: 0 }, a: { x: -1, y: 0 },
arrowright:{ x: 1, y: 0 }, d: { x: 1, y: 0 }
};
if (map[k]) nextDir = map[k];
if (k === 'p') togglePause();
if (k === 'r') init();
});

[Link]('click', togglePause);
function togglePause() {
if (gameOver) return;
paused = !paused;
[Link] = paused ? 'Reanudar' : 'Pausa';
// Pintar overlay en pausa
if (paused) {
[Link] = 'rgba(0,0,0,.45)';
[Link](0, 0, [Link], [Link]);
[Link] = '#ffffff';
[Link] = 'bold 22px Segoe UI, Arial';
[Link] = 'center';
[Link]('Pausa', [Link] / 2, [Link] / 2);
} else {
draw();
}
}

// Iniciar
init();
</script>
</body>
</html>

You might also like