rilo

A game of Snake with a disco-tiled floor - Generated by ChatGPT

Mar 16th, 2026
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 19.23 KB | Gaming | 0 0
  1.  
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5.   <meta charset="UTF-8" />
  6.   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7.   <title>Disco Snake</title>
  8.   <style>
  9.     :root {
  10.       --board-size: min(78vmin, 620px);
  11.       --tile-size: 44px;
  12.       --bg1: #ff0080;
  13.       --bg2: #00f0ff;
  14.       --bg3: #ffe600;
  15.       --bg4: #7cff00;
  16.       --panel: rgba(8, 10, 20, 0.72);
  17.       --line: rgba(255,255,255,0.14);
  18.       --text: #f6f7fb;
  19.       --shadow: 0 20px 60px rgba(0,0,0,0.35);
  20.     }
  21.  
  22.     * { box-sizing: border-box; }
  23.  
  24.     html, body {
  25.       margin: 0;
  26.       min-height: 100%;
  27.       font-family: Arial, Helvetica, sans-serif;
  28.       color: var(--text);
  29.       overflow: hidden;
  30.       background: #090909;
  31.     }
  32.  
  33.     body {
  34.       display: grid;
  35.       place-items: center;
  36.       position: relative;
  37.       isolation: isolate;
  38.     }
  39.  
  40.     body::before,
  41.     body::after {
  42.       display: none;
  43.     }
  44.  
  45.     body::before {
  46.       background: #090909;
  47.       filter: none;
  48.       opacity: 1;
  49.       animation: none;
  50.     }
  51.  
  52.     body::after {
  53.       background:
  54.         linear-gradient(90deg, rgba(255,255,255,0.1) 2px, transparent 2px),
  55.         linear-gradient(rgba(255,255,255,0.1) 2px, transparent 2px),
  56.         linear-gradient(135deg, rgba(255,255,255,0.12), rgba(255,255,255,0));
  57.       background-size: var(--tile-size) var(--tile-size), var(--tile-size) var(--tile-size), 100% 100%;
  58.       animation: danceFloor 1.8s steps(1) infinite, floorMove 7s linear infinite;
  59.       transform: perspective(1000px) rotateX(70deg) translateY(22vh) scale(1.7);
  60.       opacity: 0.85;
  61.       box-shadow: inset 0 0 120px rgba(255,255,255,0.08);
  62.     }
  63.  
  64.     .wrap {
  65.       width: min(92vw, 760px);
  66.       display: grid;
  67.       gap: 14px;
  68.       justify-items: center;
  69.       padding: 18px;
  70.     }
  71.  
  72.     .hud {
  73.       width: 100%;
  74.       display: flex;
  75.       justify-content: space-between;
  76.       gap: 12px;
  77.       padding: 14px 18px;
  78.       border-radius: 20px;
  79.       background: var(--panel);
  80.       border: 1px solid rgba(255,255,255,0.1);
  81.       box-shadow: var(--shadow);
  82.       backdrop-filter: blur(10px);
  83.       align-items: center;
  84.       flex-wrap: wrap;
  85.     }
  86.  
  87.     .title {
  88.       font-size: clamp(1.2rem, 2vw, 1.7rem);
  89.       font-weight: 700;
  90.       letter-spacing: 0.08em;
  91.       text-transform: uppercase;
  92.       text-shadow: 0 0 14px rgba(255, 0, 200, 0.45);
  93.     }
  94.  
  95.     .stats {
  96.       display: flex;
  97.       gap: 16px;
  98.       flex-wrap: wrap;
  99.       font-size: 0.98rem;
  100.     }
  101.  
  102.     .pill {
  103.       padding: 8px 12px;
  104.       border-radius: 999px;
  105.       background: rgba(255,255,255,0.08);
  106.       border: 1px solid rgba(255,255,255,0.08);
  107.       box-shadow: inset 0 0 12px rgba(255,255,255,0.04);
  108.     }
  109.  
  110.     .board-shell {
  111.       width: var(--board-size);
  112.       height: var(--board-size);
  113.       position: relative;
  114.       border-radius: 28px;
  115.       overflow: hidden;
  116.       box-shadow: var(--shadow);
  117.       border: 1px solid rgba(255,255,255,0.12);
  118.       background: rgba(8, 8, 14, 0.72);
  119.       backdrop-filter: blur(10px);
  120.     }
  121.  
  122.     canvas {
  123.       width: 100%;
  124.       height: 100%;
  125.       display: block;
  126.     }
  127.  
  128.     .overlay {
  129.       position: absolute;
  130.       inset: 0;
  131.       display: grid;
  132.       place-items: center;
  133.       background: linear-gradient(rgba(3,4,10,0.16), rgba(3,4,10,0.72));
  134.       text-align: center;
  135.       padding: 28px;
  136.       transition: opacity 0.25s ease;
  137.     }
  138.  
  139.     .overlay.hidden {
  140.       opacity: 0;
  141.       pointer-events: none;
  142.     }
  143.  
  144.     .card {
  145.       max-width: 420px;
  146.       background: rgba(12, 14, 24, 0.78);
  147.       border: 1px solid rgba(255,255,255,0.12);
  148.       border-radius: 24px;
  149.       padding: 24px;
  150.       box-shadow: var(--shadow);
  151.       backdrop-filter: blur(14px);
  152.     }
  153.  
  154.     .card h1 {
  155.       margin: 0 0 10px;
  156.       font-size: clamp(1.8rem, 4vw, 2.6rem);
  157.       line-height: 1;
  158.       text-shadow: 0 0 20px rgba(255, 0, 220, 0.45), 0 0 28px rgba(0, 220, 255, 0.35);
  159.     }
  160.  
  161.     .card p {
  162.       margin: 10px 0;
  163.       line-height: 1.45;
  164.       color: rgba(255,255,255,0.88);
  165.     }
  166.  
  167.     .keys {
  168.       display: inline-flex;
  169.       gap: 8px;
  170.       flex-wrap: wrap;
  171.       justify-content: center;
  172.       margin-top: 10px;
  173.     }
  174.  
  175.     .key {
  176.       min-width: 40px;
  177.       padding: 8px 10px;
  178.       border-radius: 12px;
  179.       background: rgba(255,255,255,0.08);
  180.       border: 1px solid rgba(255,255,255,0.14);
  181.       font-weight: 700;
  182.       box-shadow: 0 0 10px rgba(255,255,255,0.06);
  183.     }
  184.  
  185.     .button {
  186.       display: inline-block;
  187.       margin-top: 14px;
  188.       padding: 12px 18px;
  189.       border: none;
  190.       border-radius: 999px;
  191.       background: linear-gradient(135deg, #ff00cc, #00ddff);
  192.       color: white;
  193.       font-weight: 700;
  194.       letter-spacing: 0.04em;
  195.       cursor: pointer;
  196.       box-shadow: 0 10px 30px rgba(0,0,0,0.28), 0 0 18px rgba(255,0,200,0.25);
  197.     }
  198.  
  199.     .footer {
  200.       font-size: 0.92rem;
  201.       color: rgba(255,255,255,0.82);
  202.       text-align: center;
  203.       text-shadow: 0 2px 12px rgba(0,0,0,0.4);
  204.     }
  205.  
  206.     @keyframes hueShift {
  207.       0% { opacity: 1; }
  208.       100% { opacity: 1; }
  209.     }
  210.       50% { background-position: 100% 50%; filter: hue-rotate(180deg) saturate(1.5) blur(14px); }
  211.       100% { background-position: 0% 50%; filter: hue-rotate(360deg) saturate(1.3) blur(10px); }
  212.     }
  213.  
  214.     @keyframes danceFloor {
  215.       0% { opacity: 1; }
  216.       100% { opacity: 1; }
  217.     }
  218.       20%  { filter: hue-rotate(45deg) brightness(1.25); }
  219.       40%  { filter: hue-rotate(110deg) brightness(0.95); }
  220.       60%  { filter: hue-rotate(180deg) brightness(1.3); }
  221.       80%  { filter: hue-rotate(260deg) brightness(1.05); }
  222.       100% { filter: hue-rotate(360deg) brightness(1.2); }
  223.     }
  224.  
  225.     @keyframes floorMove {
  226.       0% { opacity: 1; }
  227.       100% { opacity: 1; }
  228.     }
  229.       to   { background-position: 44px 0, 0 44px, 0 0; }
  230.     }
  231.  
  232.     @media (max-width: 640px) {
  233.       :root { --tile-size: 34px; }
  234.       .hud { justify-content: center; }
  235.     }
  236.   </style>
  237. </head>
  238. <body>
  239.   <div class="wrap">
  240.     <div class="hud">
  241.       <div class="title">Disco Snake</div>
  242.       <div class="stats">
  243.         <div class="pill">Score: <strong id="score">0</strong></div>
  244.         <div class="pill">Best: <strong id="best">0</strong></div>
  245.         <div class="pill">Speed: <strong id="speed">7</strong></div>
  246.       </div>
  247.     </div>
  248.  
  249.     <div class="board-shell">
  250.       <canvas id="game" width="600" height="600"></canvas>
  251.       <div class="overlay" id="overlay">
  252.         <div class="card">
  253.           <h1>Disco Snake</h1>
  254.           <p>Eat the glowing fruit, grow longer, and survive on the flashing dance floor.</p>
  255.           <p>Use arrow keys or WASD. Press space to pause or resume.</p>
  256.           <div class="keys">
  257.             <span class="key"></span>
  258.             <span class="key"></span>
  259.             <span class="key"></span>
  260.             <span class="key"></span>
  261.             <span class="key">WASD</span>
  262.           </div>
  263.           <br />
  264.           <button class="button" id="startBtn">Start Game</button>
  265.         </div>
  266.       </div>
  267.     </div>
  268.  
  269.     <div class="footer">Single-file HTML game with a color-animated disco floor background.</div>
  270.   </div>
  271.  
  272.   <script>
  273.     const canvas = document.getElementById('game');
  274.     const ctx = canvas.getContext('2d');
  275.     const scoreEl = document.getElementById('score');
  276.     const bestEl = document.getElementById('best');
  277.     const speedEl = document.getElementById('speed');
  278.     const overlay = document.getElementById('overlay');
  279.     const startBtn = document.getElementById('startBtn');
  280.  
  281.     const gridCount = 20;
  282.     const cell = canvas.width / gridCount;
  283.     const initialSpeed = 7;
  284.     const maxSpeed = 16;
  285.     let best = Number(localStorage.getItem('discoSnakeBest') || 0);
  286.     bestEl.textContent = best;
  287.  
  288.     let snake, dir, nextDir, food, score, speed, running, paused, loopHandle;
  289.  
  290.     function randomCell(exclude = []) {
  291.       let p;
  292.       do {
  293.         p = {
  294.           x: Math.floor(Math.random() * gridCount),
  295.           y: Math.floor(Math.random() * gridCount)
  296.         };
  297.       } while (exclude.some(seg => seg.x === p.x && seg.y === p.y));
  298.       return p;
  299.     }
  300.  
  301.     function resetGame() {
  302.       snake = [
  303.         { x: 10, y: 10 },
  304.         { x: 9, y: 10 },
  305.         { x: 8, y: 10 }
  306.       ];
  307.       dir = { x: 1, y: 0 };
  308.       nextDir = { x: 1, y: 0 };
  309.       food = randomCell(snake);
  310.       score = 0;
  311.       speed = initialSpeed;
  312.       running = true;
  313.       paused = false;
  314.       updateHud();
  315.       overlay.classList.add('hidden');
  316.       cancelAnimationFrame(loopHandle);
  317.       lastStep = 0;
  318.       accumulator = 0;
  319.       loopHandle = requestAnimationFrame(gameLoop);
  320.     }
  321.  
  322.     function updateHud() {
  323.       scoreEl.textContent = score;
  324.       bestEl.textContent = best;
  325.       speedEl.textContent = speed;
  326.     }
  327.  
  328.     function setDirection(x, y) {
  329.       if (!running || paused) return;
  330.       if (x === -dir.x && y === -dir.y) return;
  331.       nextDir = { x, y };
  332.     }
  333.  
  334.     function step() {
  335.       dir = nextDir;
  336.       const head = { x: snake[0].x + dir.x, y: snake[0].y + dir.y };
  337.  
  338.       if (head.x < 0) head.x = gridCount - 1;
  339.      else if (head.x >= gridCount) head.x = 0;
  340.       if (head.y < 0) head.y = gridCount - 1;
  341.      else if (head.y >= gridCount) head.y = 0;
  342.  
  343.       if (snake.some(seg => seg.x === head.x && seg.y === head.y)) {
  344.        endGame();
  345.         return;
  346.       }
  347.  
  348.       snake.unshift(head);
  349.  
  350.       if (head.x === food.x && head.y === food.y) {
  351.        score += 10;
  352.         if (score > best) {
  353.           best = score;
  354.           localStorage.setItem('discoSnakeBest', String(best));
  355.         }
  356.         speed = Math.min(maxSpeed, initialSpeed + Math.floor(score / 40));
  357.         food = randomCell(snake);
  358.         pulseBackground();
  359.       } else {
  360.         snake.pop();
  361.       }
  362.  
  363.       updateHud();
  364.     }
  365.  
  366.     function endGame() {
  367.       running = false;
  368.       paused = false;
  369.       overlay.classList.remove('hidden');
  370.       overlay.querySelector('h1').textContent = 'Game Over';
  371.       overlay.querySelector('p').textContent = `Your score: ${score}. Ready for another round on the dance floor?`;
  372.       startBtn.textContent = 'Restart';
  373.     }
  374.  
  375.     function pulseBackground() {
  376.       document.body.animate(
  377.         [
  378.           { filter: 'brightness(1)' },
  379.           { filter: 'brightness(1.24)' },
  380.           { filter: 'brightness(1)' }
  381.         ],
  382.         { duration: 260, easing: 'ease-out' }
  383.       );
  384.       canvas.animate(
  385.         [
  386.           { transform: 'scale(1)' },
  387.           { transform: 'scale(1.012)' },
  388.           { transform: 'scale(1)' }
  389.         ],
  390.         { duration: 180, easing: 'ease-out' }
  391.       );
  392.     }
  393.  
  394.     function drawBoard() {
  395.       ctx.clearRect(0, 0, canvas.width, canvas.height);
  396.  
  397.       const t = performance.now() * 0.0015;
  398.       const globalWave = Math.sin(t * 1.7) * 18 + Math.cos(t * 1.1) * 10;
  399.  
  400.       for (let y = 0; y < gridCount; y++) {
  401.        for (let x = 0; x < gridCount; x++) {
  402.          const dx = x - gridCount / 2;
  403.          const dy = y - gridCount / 2;
  404.          const dist = Math.sqrt(dx * dx + dy * dy);
  405.  
  406.          const v =
  407.            Math.sin(x * 0.38 + t * 2.1) +
  408.            Math.sin(y * 0.42 + t * 1.8) +
  409.            Math.sin((x + y) * 0.26 + t * 1.9) +
  410.            Math.sin(dist * 0.42 - t * 2.2);
  411.  
  412.          const normalized = (v + 4) / 8;
  413.          const hue = (210 + globalWave + normalized * 70) % 360;
  414.          const light = 30 + normalized * 18;
  415.          const sat = 78 + normalized * 8;
  416.  
  417.          ctx.fillStyle = `hsl(${hue}, ${sat}%, ${light}%)`;
  418.          ctx.fillRect(x * cell, y * cell, cell, cell);
  419.  
  420.          const shine = ctx.createLinearGradient(x * cell, y * cell, x * cell + cell, y * cell + cell);
  421.          shine.addColorStop(0, 'rgba(255,255,255,0.16)');
  422.          shine.addColorStop(0.22, 'rgba(255,255,255,0.06)');
  423.          shine.addColorStop(0.55, 'rgba(255,255,255,0.015)');
  424.          shine.addColorStop(1, 'rgba(0,0,0,0.16)');
  425.          ctx.fillStyle = shine;
  426.          ctx.fillRect(x * cell, y * cell, cell, cell);
  427.        }
  428.      }
  429.  
  430.      ctx.strokeStyle = 'rgba(255,255,255,0.12)';
  431.      ctx.lineWidth = 1;
  432.      for (let i = 0; i <= gridCount; i++) {
  433.        const p = i * cell;
  434.        ctx.beginPath();
  435.        ctx.moveTo(p, 0);
  436.        ctx.lineTo(p, canvas.height);
  437.        ctx.stroke();
  438.        ctx.beginPath();
  439.        ctx.moveTo(0, p);
  440.        ctx.lineTo(canvas.width, p);
  441.        ctx.stroke();
  442.      }
  443.  
  444.      const vignette = ctx.createRadialGradient(
  445.        canvas.width / 2,
  446.        canvas.height / 2,
  447.        canvas.width * 0.12,
  448.        canvas.width / 2,
  449.        canvas.height / 2,
  450.        canvas.width * 0.78
  451.      );
  452.      vignette.addColorStop(0, 'rgba(255,255,255,0)');
  453.      vignette.addColorStop(1, 'rgba(0,0,0,0.28)');
  454.      ctx.fillStyle = vignette;
  455.      ctx.fillRect(0, 0, canvas.width, canvas.height);
  456.    }
  457.  
  458.    function drawFood() {
  459.      const px = food.x * cell + cell / 2;
  460.      const py = food.y * cell + cell / 2;
  461.      const pulse = 1 + Math.sin(performance.now() * 0.01) * 0.08;
  462.      const radius = cell * 0.28 * pulse;
  463.      const glow = ctx.createRadialGradient(px, py, 3, px, py, radius * 2.4);
  464.      glow.addColorStop(0, 'rgba(255,255,255,1)');
  465.      glow.addColorStop(0.18, 'rgba(255,240,120,0.98)');
  466.      glow.addColorStop(0.5, 'rgba(255,100,180,0.82)');
  467.      glow.addColorStop(1, 'rgba(255,40,120,0)');
  468.      ctx.fillStyle = glow;
  469.      ctx.beginPath();
  470.      ctx.arc(px, py, radius * 2.4, 0, Math.PI * 2);
  471.      ctx.fill();
  472.  
  473.      ctx.fillStyle = '#fff07a';
  474.      ctx.beginPath();
  475.      ctx.arc(px, py, radius, 0, Math.PI * 2);
  476.      ctx.fill();
  477.    }
  478.  
  479.    function drawSnake() {
  480.      const now = performance.now() * 0.12;
  481.  
  482.      snake.forEach((seg, index) => {
  483.         const x = seg.x * cell;
  484.         const y = seg.y * cell;
  485.         const inset = 3;
  486.         const w = cell - inset * 2;
  487.         const h = cell - inset * 2;
  488.         const radius = 10;
  489.         const tailRatio = snake.length > 1 ? index / (snake.length - 1) : 0;
  490.  
  491.         const g = ctx.createLinearGradient(x, y, x + cell, y + cell);
  492.         if (index === 0) {
  493.           g.addColorStop(0, '#9aff6a');
  494.           g.addColorStop(1, '#00f7c2');
  495.         } else {
  496.           const hueA = (300 + now + tailRatio * 140) % 360;
  497.           const hueB = (hueA + 42) % 360;
  498.           const lightA = 62 - tailRatio * 10;
  499.           const lightB = 54 - tailRatio * 8;
  500.           g.addColorStop(0, `hsl(${hueA}, 95%, ${lightA}%)`);
  501.           g.addColorStop(1, `hsl(${hueB}, 92%, ${lightB}%)`);
  502.         }
  503.  
  504.         ctx.save();
  505.         ctx.shadowBlur = index === 0 ? 24 : 18;
  506.         ctx.shadowColor = index === 0
  507.           ? 'rgba(0,255,210,0.75)'
  508.           : `hsla(${(320 + now + tailRatio * 120) % 360}, 100%, 65%, 0.55)`;
  509.         ctx.fillStyle = g;
  510.         roundRect(ctx, x + inset, y + inset, w, h, radius);
  511.         ctx.fill();
  512.         ctx.restore();
  513.  
  514.         ctx.strokeStyle = index === 0 ? 'rgba(255,255,255,0.22)' : 'rgba(255,255,255,0.14)';
  515.         ctx.lineWidth = 1;
  516.         roundRect(ctx, x + inset, y + inset, w, h, radius);
  517.         ctx.stroke();
  518.  
  519.         if (index > 0) {
  520.           ctx.fillStyle = `rgba(255,255,255,${0.05 - tailRatio * 0.02})`;
  521.           roundRect(ctx, x + inset + 2, y + inset + 2, w - 10, h * 0.32, 6);
  522.           ctx.fill();
  523.         }
  524.  
  525.         if (index === 0) {
  526.           const eyeOffsetX = dir.x !== 0 ? (dir.x > 0 ? 21 : 11) : 10;
  527.           const eyeOffsetY1 = dir.y !== 0 ? (dir.y > 0 ? 21 : 11) : 11;
  528.           const eyeOffsetY2 = dir.y !== 0 ? (dir.y > 0 ? 21 : 11) : 21;
  529.           const eyeX1 = x + eyeOffsetX;
  530.           const eyeX2 = dir.y !== 0 ? x + 21 : x + eyeOffsetX;
  531.           ctx.fillStyle = '#121212';
  532.           ctx.beginPath();
  533.           ctx.arc(eyeX1, y + eyeOffsetY1, 2.8, 0, Math.PI * 2);
  534.           ctx.arc(eyeX2, y + eyeOffsetY2, 2.8, 0, Math.PI * 2);
  535.           ctx.fill();
  536.         }
  537.       });
  538.     }
  539.  
  540.     function roundRect(ctx, x, y, width, height, radius) {
  541.       ctx.beginPath();
  542.       ctx.moveTo(x + radius, y);
  543.       ctx.lineTo(x + width - radius, y);
  544.       ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
  545.       ctx.lineTo(x + width, y + height - radius);
  546.       ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
  547.       ctx.lineTo(x + radius, y + height);
  548.       ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
  549.       ctx.lineTo(x, y + radius);
  550.       ctx.quadraticCurveTo(x, y, x + radius, y);
  551.       ctx.closePath();
  552.     }
  553.  
  554.     let lastStep = 0;
  555.     let accumulator = 0;
  556.  
  557.     function gameLoop(timestamp) {
  558.       if (!running) {
  559.         function sparkles() {
  560.       const now = performance.now() * 0.004;
  561.       for (let i = 0; i < 10; i++) {
  562.        const x = (Math.sin(now + i * 1.7) * 0.5 + 0.5) * canvas.width;
  563.        const y = (Math.cos(now * 1.2 + i * 2.3) * 0.5 + 0.5) * canvas.height;
  564.        const r = 1.5 + ((i % 3) * 0.8);
  565.        ctx.fillStyle = `rgba(255,255,255,${0.08 + (i % 4) * 0.03})`;
  566.        ctx.beginPath();
  567.        ctx.arc(x, y, r, 0, Math.PI * 2);
  568.        ctx.fill();
  569.      }
  570.    }
  571.  
  572.    const originalDraw = draw;
  573.    draw = function() {
  574.      drawBoard();
  575.      sparkles();
  576.      drawFood();
  577.      drawSnake();
  578.  
  579.      if (paused && running) {
  580.        ctx.fillStyle = 'rgba(8, 8, 12, 0.5)';
  581.        ctx.fillRect(0, 0, canvas.width, canvas.height);
  582.        ctx.fillStyle = '#ffffff';
  583.        ctx.font = 'bold 48px Arial';
  584.        ctx.textAlign = 'center';
  585.        ctx.fillText('PAUSED', canvas.width / 2, canvas.height / 2);
  586.      }
  587.    }
  588.  
  589.    draw();
  590.        return;
  591.      }
  592.  
  593.      if (!lastStep) lastStep = timestamp;
  594.      const delta = timestamp - lastStep;
  595.      lastStep = timestamp;
  596.      accumulator += delta;
  597.  
  598.      const interval = 1000 / speed;
  599.      while (accumulator >= interval) {
  600.         if (!paused) step();
  601.         accumulator -= interval;
  602.       }
  603.  
  604.       draw();
  605.       loopHandle = requestAnimationFrame(gameLoop);
  606.     }
  607.  
  608.     function draw() {
  609.       drawBoard();
  610.       drawFood();
  611.       drawSnake();
  612.  
  613.       if (paused && running) {
  614.        ctx.fillStyle = 'rgba(8, 8, 12, 0.5)';
  615.         ctx.fillRect(0, 0, canvas.width, canvas.height);
  616.         ctx.fillStyle = '#ffffff';
  617.         ctx.font = 'bold 48px Arial';
  618.         ctx.textAlign = 'center';
  619.         ctx.fillText('PAUSED', canvas.width / 2, canvas.height / 2);
  620.       }
  621.     }
  622.  
  623.     document.addEventListener('keydown', (e) => {
  624.       const key = e.key.toLowerCase();
  625.       if (["arrowup", "arrowdown", "arrowleft", "arrowright", " ", "w", "a", "s", "d"].includes(key)) {
  626.         e.preventDefault();
  627.       }
  628.  
  629.       if (key === 'arrowup' || key === 'w') setDirection(0, -1);
  630.       else if (key === 'arrowdown' || key === 's') setDirection(0, 1);
  631.       else if (key === 'arrowleft' || key === 'a') setDirection(-1, 0);
  632.       else if (key === 'arrowright' || key === 'd') setDirection(1, 0);
  633.       else if (key === ' ') {
  634.         if (running) paused = !paused;
  635.       }
  636.     });
  637.  
  638.     startBtn.addEventListener('click', () => {
  639.       overlay.querySelector('h1').textContent = 'Disco Snake';
  640.       overlay.querySelector('p').textContent = 'Eat the glowing fruit, grow longer, and survive on the flashing dance floor.';
  641.       startBtn.textContent = 'Start Game';
  642.       resetGame();
  643.     });
  644.  
  645.     draw();
  646.   </script>
  647. </body>
  648. </html>
  649.  
Advertisement
Add Comment
Please, Sign In to add comment