Змейка. Проекты. Ардуино

snake
Змейка на Ардуино
Змейка на Ардуино

Привет. Пришло время использовать светодиодную матрицу и джойстик для реального проекта. А что может быть лучше, чем сделать настоящую игру. Так что, сегодня соберем схему и напишем нашу версию игры змейка для Ардуино.

В прошлый раз мы уже сделали обзор на джойстик и управление светодиодом на матрице с его помощью. Посмотрите тот пост, если пропустили или уже забыли.

Для того, чтобы выполнить этот проект нам понадобиться

  • Ардуино UNO
  • Перемычки
  • Макетная плата
  • Светодиодная матрица
  • Резистор 220 Ом
  • Джойстик
  • Кабель USB

Мы уже умеем управлять одним светодиодом на матрице с помощью джойстика. Это будет основа нашей змейки. В целом, осталось добавить в программу всего несколько элементов. И она уже будет похожа на игру.

Змейка

В первую очередь сделаем, чтобы змейка двигалась сама, а при движении джойстика только меняла направление движения, если требуется.

Для этого мы должны сохранять предыдущее значение джойстика в переменных. И сравнивать их с текущем положением джойстика.

int OlddX, OlddY;

Текущие значения джойстика по X и Y сравниваются со значениями на предыдущем шаге. И если изменений нет, новое направление движения = старому.

  dX = map(dX, 0, 1000, -1, 1);
  dY = map(dY, 0, 1000, -1, 1);
  if(dX == 0 && dY == 0 && OlddX != dX){
    dX = OlddX;
  }
  if(dY == 0 && dX == 0 && OlddY != dY){
    dY = OlddY;
  }
  int newDirection = last;

Таким образом мы передадим в функцию вычисления следующего шага нужную переменную. Даже если направление движения не изменилось.

Движение в одной строке

Кроме того, нужно учесть движение змейки в одной строке и одном столбце. Чтобы змейка появлялась с другой стороны матрицы, когда она выползает за пределы поля.

Для этого изменим функцию расчета следующего шага с учетом новых требований.

Для движения по оси X это не сложно. Нужно только добавить или отнять 15 клеток от текущего индекса, в зависимости от четности строки.

  if( dX != 0 ){ // moving in X direction
    if ( row&1 ){
        if( col == 0 && dX == 1){ newDirection = last -15; } 
        else if( col == 15 && dX == -1){ newDirection = last +15; }
        else newDirection = last + dX; // четная
    } else {
        if( col == 0 && dX == 1){ newDirection = last +15; }
        else if( col == 15 && dX == -1 ){ newDirection = last -15; }
        else newDirection = last - dX; // не четная
    }
  } 

Со столбцами разобраться немного сложнее.

Нужно учесть четность строки, направление движения. Если змейка уползает за 15 строку, то все просто. Новая позиция равна номеру столбца.

А если за первую строку, то максимальное количество светодиодов в матрице — номер столбца.

  if( dY < 0){ // moving in Y DOWN direction
    if(row == 15 && dY == -1){newDirection = col;}
    else if ( row&1 ){
      newDirection = last + (col*2)+1; // четная
    } else {
      newDirection = last + (16-col-1)+(16-col); // не четная
    }
  }
  if( dY > 0){ // moving in Y UP direction
    if( row == 0 && dY == 1){ newDirection = 255 - col;}
    else if ( row&1 ){
      newDirection = last - (last - 16*row) - (16 - col); // четная
    } else {
      newDirection = last - (col*2)-1; // не четная
    }
  }

Теперь змейка не выйдет за пределы матрицы и будет двигаться самостоятельно.

Осталось только добавить для нее еды и условия проигрыша. Этим займемся в следующий раз.

Управление змейкой джойстиком
Управление змейкой джойстиком

Полный текст функции расчета движения

int Snakedirection(int last, int dX, int dY ){
  dX = map(dX, 0, 1000, -1, 1);
  dY = map(dY, 0, 1000, -1, 1);
  if(dX == 0 && dY == 0 && OlddX != dX){
    dX = OlddX;
  }
  if(dY == 0 && dX == 0 && OlddY != dY){
    dY = OlddY;
  }
  int newDirection = last;
  if( dX != 0 ){ // moving in X direction
    if ( row&1 ){
        if( col == 0 && dX == 1){ newDirection = last -15; } 
        else if( col == 15 && dX == -1){ newDirection = last +15; }
        else newDirection = last + dX; // четная
    } else {
        if( col == 0 && dX == 1){ newDirection = last +15; }
        else if( col == 15 && dX == -1 ){ newDirection = last -15; }
        else newDirection = last - dX; // не четная
    }
  } 
  if( dY < 0){ // moving in Y DOWN direction
    if(row == 15 && dY == -1){newDirection = col;}
    else if ( row&1 ){
      newDirection = last + (col*2)+1; // четная
    } else {
      newDirection = last + (16-col-1)+(16-col); // не четная
    }
  }
  if( dY > 0){ // moving in Y UP direction
    if( row == 0 && dY == 1){ newDirection = 255 - col;}
    else if ( row&1 ){
      newDirection = last - (last - 16*row) - (16 - col); // четная
    } else {
      newDirection = last - (col*2)-1; // не четная
    }
  }
  OlddX = dX;
  OlddY = dY;
  return newDirection;
}

Заключение

Мы написали первую часть игры змейка. Теперь мы можем управлять нашим героем, она двигается по игровому полю сама. Движения за пределы матрицы не происходит. И нам осталось добавить немного кода, чтобы игра стала похожа на настоящую игру.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *