Код IT Загрузка примера кода…

HTML main.html
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <title>Змейка</title>
  <style>
    body {
      margin: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background: #1e1e1e;
      font-family: sans-serif;
    }
    #gameCanvas {
      border: 2px solid #444;
      background: #000;
    }
    #score {
      position: absolute;
      top: 10px;
      left: 10px;
      color: #fff;
      font-size: 18px;
    }
    #gameOver {
      position: absolute;
      display: none;
      flex-direction: column;
      align-items: center;
      color: #fff;
      font-size: 24px;
    }
    #restartBtn {
      margin-top: 16px;
      padding: 8px 16px;
      font-size: 16px;
      background: #4CAF50;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
    }
    #restartBtn:hover {
      background: #45a049;
    }
  </style>
</head>
<body>
  <div id="score">Счёт: 0</div>
  <canvas id="gameCanvas" width="600" height="400"></canvas>
  <div id="gameOver">
    <div>Игра окончена</div>
    <button id="restartBtn">Начать заново</button>
  </div>

  <script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');
    const scoreEl = document.getElementById('score');
    const gameOverEl = document.getElementById('gameOver');
    const restartBtn = document.getElementById('restartBtn');

    const gridSize = 20;
    const cellCountX = canvas.width / gridSize;
    const cellCountY = canvas.height / gridSize;

    let snake = [{ x: 10, y: 10 }];
    let food = {};
    let direction = { x: 0, y: 0 };
    let nextDirection = { x: 0, y: 0 };
    let score = 0;
    let gameRunning = true;

    function placeFood() {
      food = {
        x: Math.floor(Math.random() * cellCountX),
        y: Math.floor(Math.random() * cellCountY)
      };
      // Избегаем генерации еды внутри змеи
      if (snake.some(segment => segment.x === food.x && segment.y === food.y)) {
        placeFood();
      }
    }

    function resetGame() {
      snake = [{ x: 10, y: 10 }];
      direction = { x: 0, y: 0 };
      nextDirection = { x: 0, y: 0 };
      score = 0;
      scoreEl.textContent = `Счёт: ${score}`;
      placeFood();
      gameOverEl.style.display = 'none';
      gameRunning = true;
    }

    function moveSnake() {
      if (!gameRunning) return;

      // Фиксируем направление только после шага (предотвращаем 180° поворот)
      direction = { ...nextDirection };

      if (direction.x === 0 && direction.y === 0) return;

      const head = { ...snake[0] };
      head.x += direction.x;
      head.y += direction.y;

      // Проверка выхода за границы
      if (head.x < 0 || head.x >= cellCountX || head.y < 0 || head.y >= cellCountY) {
        endGame();
        return;
      }

      // Проверка столкновения с собой
      if (snake.some(segment => segment.x === head.x && segment.y === head.y)) {
        endGame();
        return;
      }

      snake.unshift(head);

      // Проверка поедания еды
      if (head.x === food.x && head.y === food.y) {
        score += 10;
        scoreEl.textContent = `Счёт: ${score}`;
        placeFood();
      } else {
        snake.pop(); // Удаляем хвост, если не съели
      }
    }

    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // Змея
      snake.forEach((segment, index) => {
        ctx.fillStyle = index === 0 ? '#4CAF50' : '#8BC34A';
        ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
        ctx.strokeStyle = '#2E7D32';
        ctx.strokeRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
      });

      // Еда
      ctx.fillStyle = '#FF5252';
      ctx.beginPath();
      ctx.arc(
        (food.x + 0.5) * gridSize,
        (food.y + 0.5) * gridSize,
        gridSize / 2 - 2,
        0,
        Math.PI * 2
      );
      ctx.fill();
    }

    function gameLoop() {
      moveSnake();
      draw();
      if (gameRunning) {
        setTimeout(() => requestAnimationFrame(gameLoop), 120); // ~8.3 FPS → можно регулировать
      }
    }

    function endGame() {
      gameRunning = false;
      gameOverEl.style.display = 'flex';
    }

    // Управление
    window.addEventListener('keydown', e => {
      switch (e.key) {
        case 'ArrowUp':    if (direction.y === 0) nextDirection = { x: 0, y: -1 }; break;
        case 'ArrowDown':  if (direction.y === 0) nextDirection = { x: 0, y:  1 }; break;
        case 'ArrowLeft':  if (direction.x === 0) nextDirection = { x: -1, y: 0 }; break;
        case 'ArrowRight': if (direction.x === 0) nextDirection = { x:  1, y: 0 }; break;
        case 'w': case 'W': if (direction.y === 0) nextDirection = { x: 0, y: -1 }; break;
        case 's': case 'S': if (direction.y === 0) nextDirection = { x: 0, y:  1 }; break;
        case 'a': case 'A': if (direction.x === 0) nextDirection = { x: -1, y: 0 }; break;
        case 'd': case 'D': if (direction.x === 0) nextDirection = { x:  1, y: 0 }; break;
      }
    });

    restartBtn.addEventListener('click', resetGame);

    // Инициализация
    placeFood();
    gameLoop();
  </script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <title>Змейка</title>
  <style>
    body {
      margin: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background: #1e1e1e;
      font-family: sans-serif;
    }
    #gameCanvas {
      border: 2px solid #444;
      background: #000;
    }
    #score {
      position: absolute;
      top: 10px;
      left: 10px;
      color: #fff;
      font-size: 18px;
    }
    #gameOver {
      position: absolute;
      display: none;
      flex-direction: column;
      align-items: center;
      color: #fff;
      font-size: 24px;
    }
    #restartBtn {
      margin-top: 16px;
      padding: 8px 16px;
      font-size: 16px;
      background: #4CAF50;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
    }
    #restartBtn:hover {
      background: #45a049;
    }
  </style>
</head>
<body>
  <div id="score">Счёт: 0</div>
  <canvas id="gameCanvas" width="600" height="400"></canvas>
  <div id="gameOver">
    <div>Игра окончена</div>
    <button id="restartBtn">Начать заново</button>
  </div>

  <script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');
    const scoreEl = document.getElementById('score');
    const gameOverEl = document.getElementById('gameOver');
    const restartBtn = document.getElementById('restartBtn');

    const gridSize = 20;
    const cellCountX = canvas.width / gridSize;
    const cellCountY = canvas.height / gridSize;

    let snake = [{ x: 10, y: 10 }];
    let food = {};
    let direction = { x: 0, y: 0 };
    let nextDirection = { x: 0, y: 0 };
    let score = 0;
    let gameRunning = true;

    function placeFood() {
      food = {
        x: Math.floor(Math.random() * cellCountX),
        y: Math.floor(Math.random() * cellCountY)
      };
      // Избегаем генерации еды внутри змеи
      if (snake.some(segment => segment.x === food.x && segment.y === food.y)) {
        placeFood();
      }
    }

    function resetGame() {
      snake = [{ x: 10, y: 10 }];
      direction = { x: 0, y: 0 };
      nextDirection = { x: 0, y: 0 };
      score = 0;
      scoreEl.textContent = `Счёт: ${score}`;
      placeFood();
      gameOverEl.style.display = 'none';
      gameRunning = true;
    }

    function moveSnake() {
      if (!gameRunning) return;

      // Фиксируем направление только после шага (предотвращаем 180° поворот)
      direction = { ...nextDirection };

      if (direction.x === 0 && direction.y === 0) return;

      const head = { ...snake[0] };
      head.x += direction.x;
      head.y += direction.y;

      // Проверка выхода за границы
      if (head.x < 0 || head.x >= cellCountX || head.y < 0 || head.y >= cellCountY) {
        endGame();
        return;
      }

      // Проверка столкновения с собой
      if (snake.some(segment => segment.x === head.x && segment.y === head.y)) {
        endGame();
        return;
      }

      snake.unshift(head);

      // Проверка поедания еды
      if (head.x === food.x && head.y === food.y) {
        score += 10;
        scoreEl.textContent = `Счёт: ${score}`;
        placeFood();
      } else {
        snake.pop(); // Удаляем хвост, если не съели
      }
    }

    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // Змея
      snake.forEach((segment, index) => {
        ctx.fillStyle = index === 0 ? '#4CAF50' : '#8BC34A';
        ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
        ctx.strokeStyle = '#2E7D32';
        ctx.strokeRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
      });

      // Еда
      ctx.fillStyle = '#FF5252';
      ctx.beginPath();
      ctx.arc(
        (food.x + 0.5) * gridSize,
        (food.y + 0.5) * gridSize,
        gridSize / 2 - 2,
        0,
        Math.PI * 2
      );
      ctx.fill();
    }

    function gameLoop() {
      moveSnake();
      draw();
      if (gameRunning) {
        setTimeout(() => requestAnimationFrame(gameLoop), 120); // ~8.3 FPS → можно регулировать
      }
    }

    function endGame() {
      gameRunning = false;
      gameOverEl.style.display = 'flex';
    }

    // Управление
    window.addEventListener('keydown', e => {
      switch (e.key) {
        case 'ArrowUp':    if (direction.y === 0) nextDirection = { x: 0, y: -1 }; break;
        case 'ArrowDown':  if (direction.y === 0) nextDirection = { x: 0, y:  1 }; break;
        case 'ArrowLeft':  if (direction.x === 0) nextDirection = { x: -1, y: 0 }; break;
        case 'ArrowRight': if (direction.x === 0) nextDirection = { x:  1, y: 0 }; break;
        case 'w': case 'W': if (direction.y === 0) nextDirection = { x: 0, y: -1 }; break;
        case 's': case 'S': if (direction.y === 0) nextDirection = { x: 0, y:  1 }; break;
        case 'a': case 'A': if (direction.x === 0) nextDirection = { x: -1, y: 0 }; break;
        case 'd': case 'D': if (direction.x === 0) nextDirection = { x:  1, y: 0 }; break;
      }
    });

    restartBtn.addEventListener('click', resetGame);

    // Инициализация
    placeFood();
    gameLoop();
  </script>
</body>
</html>