Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 04.10.2020, 13:21
Аспирант
Отправить личное сообщение для Alena_03 Посмотреть профиль Найти все сообщения от Alena_03
 
Регистрация: 06.09.2020
Сообщений: 57

Змейка, подсчёт очков
Нужно сделать подсчёт очков в игре, подскажите, как реализовать?
<!DOCTYPE html>
<html>
<head>
  <title>Змейка</title>
  <style>
    html,
    body {
      height: 100%;
      margin: 0;
    }

    /*Задаём глобальные параметры*/
    body {
      background: black;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    /*Делаем границу вокруг игрового поля*/
    canvas {
      border: 1px solid white;
    }
  </style>
</head>

<body>
  <!-- Рисуем игровое поле -->
  <canvas width="400" height="400" id="game"></canvas>
  <!-- Сам скрипт с игрой -->
  <script>
    // Поле, на котором всё будет происходить, — тоже как бы переменная
    var canvas = document.getElementById('game');
    // Классическая змейка — двухмерная, сделаем такую же
    var context = canvas.getContext('2d');
    // Размер одной клеточки на поле — 16 пикселей
    var grid = 16;
    // Служебная переменная, которая отвечает за скорость змейки
    var count = 0;
    // А вот и сама змейка
    var = score; // подсчёт очков
    var snake = {
      // Начальные координаты
      x: 160,
      y: 160,
      // Скорость змейки — в каждом новом кадре змейка смещается по оси Х или У. На старте будет двигаться горизонтально, поэтому скорость по игреку равна нулю.
      dx: grid,
      dy: 0,
      // Тащим за собой хвост, который пока пустой
      cells: [],
      // Стартовая длина змейки — 4 клеточки
      maxCells: 4
    };
    // А это — еда. Представим, что это красные яблоки.
    var apple = {
      // Начальные координаты яблока
      x: 320,
      y: 320
    };
    // Делаем генератор случайных чисел в заданном диапазоне
    function getRandomInt(min, max) {
      return Math.floor(Math.random() * (max - min)) + min;
    }
    // Игровой цикл — основной процесс, внутри которого будет всё происходить
    function loop() {
      // Хитрая функция, которая замедляет скорость игры с 60 кадров в секунду до 15 (60/15 = 4)
      requestAnimationFrame(loop);
      // Игровой код выполнится только один раз из четырёх, в этом и суть замедления кадров, а пока переменная count меньше четырёх, код выполняться не будет
      if (++count < 4) {
        return;
      }
      // Обнуляем переменную скорости
      count = 0;
      // Очищаем игровое поле
      context.clearRect(0, 0, canvas.width, canvas.height);
      // Двигаем змейку с нужной скоростью
      snake.x += snake.dx;
      snake.y += snake.dy;
      // Если змейка достигла края поля по горизонтали — продолжаем её движение с противоположной строны
      if (snake.x < 0) {
       context.clearRect(0, 0, canvas.width, canvas.height);
       alert('Game over');
            snake.x = 160;
            snake.y = 160;
            snake.cells = [];
            snake.maxCells = 4;
            snake.dx = grid;
            snake.dy = 0;
            // Ставим яблочко в случайное место
            apple.x = getRandomInt(0, 25) * grid;
            apple.y = getRandomInt(0, 25) * grid;
      }
      else if (snake.x >= canvas.width) {
        context.clearRect(0, 0, canvas.width, canvas.height);
        alert('Game over');
            snake.x = 160;
            snake.y = 160;
            snake.cells = [];
            snake.maxCells = 4;
            snake.dx = grid;
            snake.dy = 0;
            // Ставим яблочко в случайное место
            apple.x = getRandomInt(0, 25) * grid;
            apple.y = getRandomInt(0, 25) * grid;
      }
      // Делаем то же самое для движения по вертикали
      if (snake.y < 0) {
        context.clearRect(0, 0, canvas.width, canvas.height);
        alert('Game over');
            snake.x = 160;
            snake.y = 160;
            snake.cells = [];
            snake.maxCells = 4;
            snake.dx = grid;
            snake.dy = 0;
            // Ставим яблочко в случайное место
            apple.x = getRandomInt(0, 25) * grid;
            apple.y = getRandomInt(0, 25) * grid;
      }
      else if (snake.y >= canvas.height) {
        context.clearRect(0, 0, canvas.width, canvas.height);
        alert('Game over');
            snake.x = 160;
            snake.y = 160;
            snake.cells = [];
            snake.maxCells = 4;
            snake.dx = grid;
            snake.dy = 0;
            // Ставим яблочко в случайное место
            apple.x = getRandomInt(0, 25) * grid;
            apple.y = getRandomInt(0, 25) * grid;
      }
      // Продолжаем двигаться в выбранном направлении. Голова всегда впереди, поэтому добавляем её координаты в начало массива, который отвечает за всю змейку
      snake.cells.unshift({ x: snake.x, y: snake.y });
      // Сразу после этого удаляем последний элемент из массива змейки, потому что она движется и постоянно освобождает клетки после себя
      if (snake.cells.length > snake.maxCells) {
        snake.cells.pop();
      }
      // Рисуем еду — красное яблоко
      context.fillStyle = 'red';
      context.fillRect(apple.x, apple.y, grid - 1, grid - 1);
      // Одно движение змейки — один новый нарисованный квадратик 
      context.fillStyle = 'green';
      // Обрабатываем каждый элемент змейки
      snake.cells.forEach(function (cell, index) {
        // Чтобы создать эффект клеточек, делаем зелёные квадратики меньше на один пиксель, чтобы вокруг них образовалась чёрная граница
        context.fillRect(cell.x, cell.y, grid - 1, grid - 1);
        // Если змейка добралась до яблока...
        if (cell.x === apple.x && cell.y === apple.y) {
          // увеличиваем длину змейки
          snake.maxCells++;
          // Рисуем новое яблочко
          // Помним, что размер холста у нас 400x400, при этом он разбит на ячейки — 25 в каждую сторону
          apple.x = getRandomInt(0, 25) * grid;
          apple.y = getRandomInt(0, 25) * grid;
        }
        // Проверяем, не столкнулась ли змея сама с собой
        // Для этого перебираем весь массив и смотрим, есть ли у нас в массиве змейки две клетки с одинаковыми координатами 
        for (var i = index + 1; i < snake.cells.length; i++) {
          // Если такие клетки есть — начинаем игру заново
          if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) {
            // Задаём стартовые параметры основным переменным
             context.clearRect(0, 0, canvas.width, canvas.height);
            alert('Game over');
            snake.x = 160;
            snake.y = 160;
            snake.cells = [];
            snake.maxCells = 4;
            snake.dx = grid;
            snake.dy = 0;
            // Ставим яблочко в случайное место
            apple.x = getRandomInt(0, 25) * grid;
            apple.y = getRandomInt(0, 25) * grid;
          }
        }
      });
    }
    // Смотрим, какие нажимаются клавиши, и реагируем на них нужным образом
    document.addEventListener('keydown', function (e) {
      // Дополнительно проверяем такой момент: если змейка движется, например, влево, то ещё одно нажатие влево или вправо ничего не поменяет — змейка продолжит двигаться в ту же сторону, что и раньше. Это сделано для того, чтобы не разворачивать весь массив со змейкой на лету и не усложнять код игры.
      // Стрелка влево
      // Если нажата стрелка влево, и при этом змейка никуда не движется по горизонтали…
      if (e.which === 37 && snake.dx === 0) {
        // то даём ей движение по горизонтали, влево, а вертикальное — останавливаем
        // Та же самая логика будет и в остальных кнопках
        snake.dx = -grid;
        snake.dy = 0;
      }
      // Стрелка вверх
      else if (e.which === 38 && snake.dy === 0) {
        snake.dy = -grid;
        snake.dx = 0;
      }
      // Стрелка вправо
      else if (e.which === 39 && snake.dx === 0) {
        snake.dx = grid;
        snake.dy = 0;
      }
      // Стрелка вниз
      else if (e.which === 40 && snake.dy === 0) {
        snake.dy = grid;
        snake.dx = 0;
      }
    });
    // Запускаем игру
    requestAnimationFrame(loop);
  </script>
</body>

</html>
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Подсчет оценок в тесте chekbox Freestyle007 Events/DOM/Window 21 28.06.2019 11:50
Подсчет количества запросов к API _marisha Общие вопросы Javascript 1 20.09.2018 11:03
еще змейка на js JSN Ваши сайты и скрипты 7 04.08.2013 22:45
Змейка: совпадение координат Hekumok Общие вопросы Javascript 16 24.04.2013 19:38
Подсчет оценок asdasdasd Общие вопросы Javascript 6 06.10.2010 21:18