diff --git a/README.md b/README.md index 3a0abf4..ecfe000 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The classic Snake game. It runs in your web browser from a single file and works 3. Press any arrow key, or click **Start**, to begin. - **Arrow keys** move the snake. -- Eat the **red food** to grow and score a point. The snake speeds up a little each time it eats. +- Eat the **glowing pink food** to grow and score a point. The snake speeds up a little each time it eats. - The game ends if you hit a wall or your own tail. - On the Game Over screen, click **Play Again** or press **Space** or **Enter** to restart. - Press **P** to pause and resume. diff --git a/index.html b/index.html index 943eba4..db8325f 100644 --- a/index.html +++ b/index.html @@ -13,11 +13,17 @@ flex-direction: column; align-items: center; justify-content: center; - background: #1b1f2a; + background: radial-gradient(ellipse at center, #120a24 0%, #07040f 70%); color: #e8ecf1; font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; } - h1 { margin: 0 0 12px; font-size: 2rem; letter-spacing: 2px; } + h1 { + margin: 0 0 12px; + font-size: 2.2rem; + letter-spacing: 6px; + color: #e9fffb; + text-shadow: 0 0 4px #fff, 0 0 10px #00fff0, 0 0 22px #00fff0, 0 0 40px #00b3ff; + } .scores { display: flex; justify-content: space-between; @@ -26,7 +32,7 @@ margin-bottom: 8px; font-size: 1.1rem; } - .scores strong { color: #7ee787; } + .scores strong { color: #39ff14; text-shadow: 0 0 6px #39ff14, 0 0 14px #39ff14; } .board { position: relative; width: 400px; @@ -37,9 +43,10 @@ display: block; width: 100%; height: 100%; - background: #0f131b; - border: 3px solid #3a4152; + background: #05030c; + border: 2px solid #00fff0; border-radius: 6px; + box-shadow: 0 0 8px #00fff0, 0 0 24px rgba(0, 255, 240, 0.45), inset 0 0 18px rgba(0, 255, 240, 0.25); } .overlay { position: absolute; @@ -49,26 +56,41 @@ align-items: center; justify-content: center; text-align: center; - background: rgba(10, 12, 18, 0.82); + background: rgba(5, 3, 12, 0.85); border-radius: 6px; padding: 20px; } .hidden { display: none !important; } - .overlay h2 { margin: 0 0 10px; font-size: 1.8rem; } - .overlay p { margin: 6px 0; color: #b8c0cc; } + .overlay h2 { + margin: 0 0 10px; + font-size: 1.8rem; + color: #ffe6fb; + text-shadow: 0 0 4px #fff, 0 0 10px #ff2bd6, 0 0 22px #ff2bd6; + } + .overlay p { margin: 6px 0; color: #c9c3e0; } .overlay button { margin-top: 14px; padding: 10px 26px; font-size: 1.1rem; font-weight: bold; - color: #0f131b; - background: #7ee787; - border: none; + color: #39ff14; + background: transparent; + border: 2px solid #39ff14; border-radius: 6px; cursor: pointer; + text-shadow: 0 0 6px #39ff14; + box-shadow: 0 0 8px #39ff14, inset 0 0 8px rgba(57, 255, 20, 0.4); + transition: background 0.15s, color 0.15s, box-shadow 0.15s; + } + .overlay button:hover, + .overlay button:focus-visible { + outline: none; + color: #05030c; + background: #39ff14; + text-shadow: none; + box-shadow: 0 0 14px #39ff14, 0 0 30px #39ff14; } - .overlay button:hover { background: #a5f3ad; } - .help { margin-top: 12px; color: #8b93a1; font-size: 0.9rem; } + .help { margin-top: 12px; color: #8a7fb0; font-size: 0.9rem; }
@@ -83,7 +105,7 @@ @@ -242,8 +264,10 @@ } } - function drawCell(x, y, color, inset) { + function drawCell(x, y, color, inset, glow) { ctx.fillStyle = color; + ctx.shadowColor = glow || color; + ctx.shadowBlur = glow ? 14 : 0; const r = 4; const px = x * CELL + inset, py = y * CELL + inset, size = CELL - inset * 2; ctx.beginPath(); @@ -255,29 +279,53 @@ function draw(dead) { ctx.clearRect(0, 0, canvas.width, canvas.height); - // subtle grid - ctx.fillStyle = "#141924"; - for (let x = 0; x < GRID; x++) { - for (let y = 0; y < GRID; y++) { - if ((x + y) % 2 === 0) ctx.fillRect(x * CELL, y * CELL, CELL, CELL); - } + // faint neon grid lines + ctx.shadowBlur = 0; + ctx.strokeStyle = "rgba(140, 60, 255, 0.14)"; + ctx.lineWidth = 1; + ctx.beginPath(); + for (let i = 1; i < GRID; i++) { + ctx.moveTo(i * CELL + 0.5, 0); + ctx.lineTo(i * CELL + 0.5, canvas.height); + ctx.moveTo(0, i * CELL + 0.5); + ctx.lineTo(canvas.width, i * CELL + 0.5); } + ctx.stroke(); if (food) { - ctx.fillStyle = "#ff5c5c"; + const fx0 = food.x * CELL + CELL / 2, fy0 = food.y * CELL + CELL / 2; + ctx.shadowColor = "#ff2bd6"; + ctx.shadowBlur = 22; + ctx.fillStyle = "#ff2bd6"; + ctx.beginPath(); + ctx.arc(fx0, fy0, CELL / 2 - 4, 0, Math.PI * 2); + ctx.fill(); + // bright hot core + ctx.shadowBlur = 8; + ctx.fillStyle = "#ffd6f7"; ctx.beginPath(); - ctx.arc(food.x * CELL + CELL / 2, food.y * CELL + CELL / 2, CELL / 2 - 3, 0, Math.PI * 2); + ctx.arc(fx0, fy0, CELL / 6, 0, Math.PI * 2); ctx.fill(); } - snake.forEach((s, i) => { - const color = dead ? (i === 0 ? "#c9a227" : "#8a7a3a") : (i === 0 ? "#a5f3ad" : "#3fb950"); - drawCell(s.x, s.y, color, 1); - }); + // draw tail first so the head's glow sits on top + for (let i = snake.length - 1; i >= 0; i--) { + const s = snake[i]; + let color, glow; + if (dead) { + color = i === 0 ? "#ff9a3c" : "#8a3a1a"; + glow = i === 0 ? "#ff6a00" : null; + } else { + color = i === 0 ? "#c8ffb8" : "#39ff14"; + glow = "#39ff14"; + } + drawCell(s.x, s.y, color, 2, glow); + } + ctx.shadowBlur = 0; // eyes on the head const h = snake[0]; - ctx.fillStyle = "#0f131b"; + ctx.fillStyle = "#05030c"; const cx = h.x * CELL + CELL / 2, cy = h.y * CELL + CELL / 2; const off = CELL / 5; const ex = direction.y !== 0 ? off : 0, ey = direction.x !== 0 ? off : 0;