Как создать анимацию змейка?

Для создания анимации змейки в JavaScript вам понадобится использовать Canvas API и алгоритмы движения. Давайте разобьем эту задачу на несколько шагов:

1. Создание холста:
Начнем с создания холста, на котором будет отображаться анимация. Для этого нам понадобится HTML-элемент canvas. Воспользуемся следующим кодом:

<canvas id="canvas" width="400" height="400"></canvas>

2. Отрисовка змейки:
Создадим класс Snake, который будет отвечать за отрисовку и движение змейки на холсте. Змейка будет представлена массивом сегментов, каждый из которых будет обозначен координатами (x, y). Добавим метод draw, который будет пробегать по массиву сегментов и отрисовывать их на холсте с помощью метода fillRect контекста canvas.

class Snake {
  constructor() {
    this.segments = [{ x: 0, y: 0 }, { x: 20, y: 0 }, { x: 40, y: 0 }];
    this.direction = 'right';
  }

  draw(ctx) {
    this.segments.forEach(segment => {
      ctx.fillStyle = 'green';
      ctx.fillRect(segment.x, segment.y, 20, 20);
    });
  }
}

3. Движение змейки:
Добавим метод move класса Snake, который будет обновлять позицию змейки в зависимости от текущего направления. Мы будем использовать setInterval, чтобы вызывать этот метод периодически и обновлять анимацию.

class Snake {
  // ...

  move() {
    const head = { x: this.segments[0].x, y: this.segments[0].y };

    switch (this.direction) {
      case 'up':
        head.y -= 20;
        break;
      case 'down':
        head.y += 20;
        break;
      case 'left':
        head.x -= 20;
        break;
      case 'right':
        head.x += 20;
        break;
    }

    this.segments.unshift(head);
    this.segments.pop();
  }
}

4. Обработка событий клавиатуры:
Добавим обработчик событий клавиатуры, который будет изменять направление движения змейки в зависимости от нажатой клавиши.

document.addEventListener('keydown', e => {
  switch (e.key) {
    case 'ArrowUp':
      snake.direction = 'up';
      break;
    case 'ArrowDown':
      snake.direction = 'down';
      break;
    case 'ArrowLeft':
      snake.direction = 'left';
      break;
    case 'ArrowRight':
      snake.direction = 'right';
      break;
  }
});

5. Отображение анимации:
Создадим функцию animate, которая будет вызываться периодически с помощью requestAnimationFrame и будет отвечать за отображение анимации змейки. Внутри этой функции мы будем очищать холст, двигать змейку и отрисовывать ее заново.

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

  requestAnimationFrame(animate);
}

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const snake = new Snake();

animate();

6. Добавление пищи для змейки:
Для добавления пищи в игру, создадим класс Food, который будет отвечать за отрисовку и позиционирование еды на холсте.

class Food {
  constructor() {
    this.x = Math.floor(Math.random() * (canvas.width / 20)) * 20;
    this.y = Math.floor(Math.random() * (canvas.height / 20)) * 20;
  }

  draw(ctx) {
    ctx.fillStyle = 'red';
    ctx.fillRect(this.x, this.y, 20, 20);
  }
}

Мы можем добавить объект Food в нашу игру и проверять, столкнулась ли голова змейки с едой. Если это произошло, мы можем увеличить размер змейки, добавив новый сегмент в начало массива segments.

class Snake {
  // ...

  checkCollisionWithFood(food) {
    const head = this.segments[0];

    return head.x === food.x && head.y === food.y;
  }

  eatFood(food) {
    if (this.checkCollisionWithFood(food)) {
      this.segments.unshift(food);
      return true;
    }

    return false;
  }
}

const food = new Food();

if (snake.eatFood(food)) {
  food = new Food();
}

food.draw(ctx);

Это лишь основы создания анимации змейки в JavaScript. Вы можете добавить дополнительные возможности, такие как проверка на столкновение змейки с самой собой, счет и отображение сообщения о проигрыше.