void begin1()
{
  myGLCD.setFont(Ubuntubold);
  myFiles.load(0, 0, 800, 480, "play/21.raw" , 32, 0);

  delay(5000);
  //myGLCD.fillScr(67,200,81);
  myFiles.load(0, 0, 800, 480, "play/20.raw" , 32, 0);
  nTail = 3;                                                                          // Назначаем количество элементов в змейке 3.
  del = 600;                                                                          // Присваиваем переменной значение задержки 200 мс.
  yz = random(5, 11);                                                                  // Начальное положение Y-координаты.
  xz = random(5, 11);                                                                  // Начальное положение X-координаты.
  Choice = random(1, 4);                                                              // Начальное направление движения.
  //
  for (int i = 0; i <= nTail - 1; i++)                                                // Формируем змейку из трех элементов в зависимости от направления движения. Присваиваем координаты каждому элементу змейке.
  { //
    Tail[i] = yz;                                                                    // Присваиваем Y-координату элементу массива.
    Tail[i] = Tail[i] << 8;                                                         // Сдвигаем побитно на 8.
    Tail[i] += xz;                                                                   // Присваиваем X-координату элементу массива.
    switch (Choice)                                                                 // В зависимости от направления движения формируем хвост в противоположную сторону.
    { //
      case 1:                                                                     // Движение вверх.
        xz++;                                                                      // Формируем хвост змейки вниз.
        break;                                                                    //
      case 2:                                                                     // Движение вниз.
        xz--;                                                                      // Формируем хвост змейки вверх.
        break;                                                                    //
      case 3:                                                                     // Движение влево.
        yz++;                                                                      // Формируем хвост змейки вправо.
        break;                                                                    //
      case 4:                                                                     // Движение вправо.
        yz--;                                                                      // Формируем хвост змейки влево.
        break;                                                                    //
    }                                                                             //
  }                                                                                 //
  myGLCD.setColor(VGA_BLUE);
  if (grad == 0) myGLCD.drawBitmap (highByte(Tail[nTail - 1])*Xk, lowByte(Tail[nTail - 1])*Xk, 30, 30, zmeygol); //
  // myGLCD.fillRect(highByte(Tail[nTail-1])*Xk, lowByte(Tail[nTail-1])*Xk, highByte(Tail[nTail-1])*Xk+Xk, lowByte(Tail[nTail-1])*Xk+Xk);//
  for (int i = 0; i <= nTail - 2; i++) {
    myGLCD.setColor(VGA_RED);
    if (grad == 0) myGLCD.drawBitmap (highByte(Tail[i])*Xk, lowByte(Tail[i])*Xk, 30, 30, zmeygol); //
    // myGLCD.fillRect(highByte(Tail[i])*Xk, lowByte(Tail[i])*Xk, highByte(Tail[i])*Xk+Xk, lowByte(Tail[i])*Xk+Xk);
    myGLCD.setBackColor(VGA_TRANSPARENT);
    myGLCD.setColor(VGA_WHITE);
    myGLCD.printNumI(nTail - 3, 580, 389);
  }
  //
  CoreY = random(2, 14);                                                              // Задаем Y-координату положения квадратика.
  CoreX = random(2, 14);                                                              // Задаем X-координату положения квадратика.
  myGLCD.setColor(VGA_YELLOW);
  // myGLCD.fillRect (CoreY*Xk, CoreX*Xk,  CoreY*Xk + Xk, CoreX*Xk + Xk);            // Выводим квадратик
  myGLCD.drawBitmap (CoreY * Xk, CoreX * Xk, 30, 30, apple);
  yz = highByte(Tail[0]);                                                              // Y-координату первого элемента массива присваиваем начальной Y-координате движения.
  xz = lowByte(Tail[0]);
}


void zmeyka() {


  begin1();

  while (1)
  {
    Keys();
    SpeedControl() ;
    Keys();
    myGLCD.setColor(VGA_WHITE);                                                                                     //
    myGLCD.drawRect   (0, 0, 480, 479);                                      // Обновляем каждый шаг рамку игрового поля.
    myGLCD.drawRect   (1, 1, 479, 478);                                      // Обновляем каждый шаг рамку игрового поля.
    myGLCD.drawRect   (2, 2, 478, 477);                                      // Обновляем каждый шаг рамку игрового поля.
    myGLCD.setColor(VGA_YELLOW);
    // myGLCD.fillRect (CoreY*Xk, CoreX*Xk,  CoreY*Xk + Xk, CoreX*Xk + Xk);            // Обновляем каждый шаг квадратик.
    myGLCD.drawBitmap (CoreY * Xk, CoreX * Xk, 30, 30, apple);
    //
    EndY = highByte(Tail[nTail - 1]);                                                   // Запоминаем Y-координаты последнего элемента массива.
    EndX = lowByte(Tail[nTail - 1]);                                                    // Запоминаем Y-координаты последнего элемента массива.
    Keys();
    MoveControl();
    //
    int PrevSY = highByte(Tail[0]);                                                     // Дополнительная переменная для переноса Y-координаты массива.
    int PrevSX = lowByte(Tail[0]);                                                      // Дополнительная переменная для переноса X-координаты массива.
    int Prev2SX, Prev2SY;                                                               // Вторые дополнительные переменные для переноса координат массива.
    Tail[0] = yz;                                                                        // Присваиваем новую Y-координату первому элементу массива.
    Tail[0] = Tail[0] << 8;                                                             // Сдвигаем побитно на 8.
    Tail[0] += xz;                                                                       // Присваиваем новую X-координату первому элементу массива.
    for (int i = 1; i <= nTail - 1; i++)                                                // Переносим каждый элемент массива по очереди с помощью цикла.
    { //
      Prev2SY = highByte(Tail[i]);                                                      // Присваиваем второй дополнительное переменной Y-координату массива.
      Prev2SX = lowByte(Tail[i]);                                                       // Присваиваем второй дополнительное переменной X-координату массива.
      Tail[i] = PrevSY;                                                                 // Присваиваем новому элементу массива старую Y-координату предыдущего элемента массива.
      Tail[i] = Tail[i] << 8;                                                           // Сдвигаем побитно на 8.
      Tail[i] += PrevSX;                                                                // Присваиваем новому элементу массива старую X-координату предыдущего элемента массива.
      PrevSY = Prev2SY;                                                                 // Присваиваем дополнительным переменным с Y-координатой вторые дополнительные переменные с Y-координатой.
      PrevSX = Prev2SX;                                                                 // Присваиваем дополнительным переменным с X-координатой вторые дополнительные переменные с X-координатой.
    }
    //31 на 14
    if (xz > 15 || xz < 0 || yz > 15 || yz < 0) {                                           // Проверка выхода змейки за пределы игрового поля. Если координат движения больше, чем игровое поле, то игра заканчивается.
      GameOver();                                                                         // Функция завершения игры.
      ShowSnake();
      begin1();
    }


    myGLCD.setColor(VGA_BLUE);
    // myGLCD.fillRect(highByte(Tail[0])*Xk, lowByte(Tail[0])*Xk, highByte(Tail[0])*Xk+Xk, lowByte(Tail[0])*Xk+Xk);

    if (grad == 0) myGLCD.drawBitmap (highByte(Tail[0])*Xk, lowByte(Tail[0])*Xk, 30, 30, zmeygol); //
    if (grad == 1) myGLCD.drawBitmap (highByte(Tail[0])*Xk, lowByte(Tail[0])*Xk, 30, 30, zmeygol1); //
    if (grad == 2) myGLCD.drawBitmap (highByte(Tail[0])*Xk, lowByte(Tail[0])*Xk, 30, 30, zmeygol2); //
    if (grad == 3) myGLCD.drawBitmap (highByte(Tail[0])*Xk, lowByte(Tail[0])*Xk, 30, 30, zmeygol3); //


    for (int i = 1; i <= nTail - 1; i++) {                                              // Выводим змейку на экран.
      myGLCD.setColor(VGA_RED);
      // myGLCD.fillRect(highByte(Tail[i])*Xk, lowByte(Tail[i])*Xk,  highByte(Tail[i])*Xk + Xk, lowByte(Tail[i])*Xk + Xk);

      myGLCD.drawBitmap (highByte(Tail[i])*Xk, lowByte(Tail[i])*Xk, 30, 30, zmeytelo);
    }
    //
    myGLCD.setColor(67, 200, 81);
    myGLCD.fillRect   (EndY * Xk, EndX * Xk,  EndY * Xk + Xk, EndX * Xk + Xk);      // Очищаем последний элемент змейки.
    // myOLED.update();
    Keys();
    if (xz == CoreX && yz == CoreY)                                                       // Сравниваем координаты змейки с координатами квадратика.
    {
      myGLCD.setColor(250, 250, 250);
      // myGLCD.fillRect(CoreY*Xk, CoreX*Xk,  CoreY*Xk + Xk, CoreX*Xk + Xk);          // Если они совпадают, очищаем старый квадратик.
      CoreY = random(2, 14);                                                            // Задаем новую Y-координату квадратика.
      CoreX = random(2, 14);                                                            // Задаем новую X-координату квадратика.
      nTail++;                                                                          // Увеличиваем количество элементов в змейке на один.
      myGLCD.setBackColor(67, 200, 81);
      myGLCD.setColor(VGA_WHITE);

      myGLCD.printNumI(nTail - 3, 580, 389);
    }                                                                                   //
    // Функция вывода всей змейки на экран после проигрыша.
    //
    for (int i = 1; i < nTail - 1; i++) {                                               // Проверки столкновения головы змейки с хвостом.
      if (yz == highByte(Tail[i]) && xz == lowByte(Tail[i])) {                              // С помощью цикла проверяем каждый элемент массива с координатами движения. Если они совпадают, то голова столкнулась с хвостом.
        GameOver();                                                                         // Функция завершения игры.
        ShowSnake();
        begin1();
      }
    }
  }
}
//***************************************************************************************************************************
// Функция регулировки скорости.
void SpeedControl()                                                                   //
{ //
  delay (del);                                                                        // Регулируем скорость змейки. Первая скорость - задержка 200 мс.
  if (nTail == 5) {
    del = 400; // Вторая скорость. Задержка 100 мс. Количество элементов змейки = 5.
  }
  if (nTail == 10) {
    del = 350; // Третья скорость. Задержка 50 мс. Количество элементов змейки = 10.
  }
  if (nTail == 15) {
    del = 250; // Четвертая скорость. Задержки нет. Количество элементов змейки = 15.
  }
  if (nTail == 20) {
    del = 100;
  }
}

void MoveControl()                                                                    //
{ //

  // **КНОПКИ  ЦВЕТ*****************************
  myGLCD.setColor(100, 100, 250);
  myGLCD.drawLine(503, 29, 503 + 60, 29);
  myGLCD.drawLine(503, 30, 503 + 60, 30);
  myGLCD.drawLine(503, 239, 503 + 60, 239);
  myGLCD.drawLine(503, 240, 503 + 60, 240);
  myGLCD.drawLine(610, 132, 610 + 60, 132);
  myGLCD.drawLine(610, 133, 610 + 60, 133);
  myGLCD.drawLine(610, 344, 610 + 60, 344);
  myGLCD.drawLine(610, 345, 610 + 60, 345);
  myGLCD.drawLine(713, 239, 713 + 60, 239);
  myGLCD.drawLine(713, 240, 713 + 60, 240);

  //***************************************************
  switch (Choice)                                                                     //
  {

    case 3: //влево                                                                        // Движение влево.
      grad = 0;
      if (valBtnT == 1)
      { valBtnT = 0;
        Choice = 2;
      }             //верх Проверяем данные по оси Y. Поворот вверх.
      if (valBtnD == 1)
      { valBtnD = 0;
        Choice = 1;
      }
      // if (sensor.axisX >= -2 && sensor.axisY <= MIN_VALUE){Choice = 2;}             // Проверяем данные по оси Y. Поворот вниз.
      yz++;
      // Координаты формирования змейки при движении влево. Уменьшаем координату Y на количество пройденных квадратиков.
      break;                                                                        //
    //
    case 4: // право
      grad = 2;
      if (valBtnD == 1)
      { valBtnD = 0;
        Choice = 1;
      }//низ Движение вправо
      if (valBtnT == 1)
      { valBtnT = 0;
        Choice = 2;
      }

      // if (sensor.axisX <= 2 && sensor.axisY >= MAX_VALUE){Choice = 1;}              // Проверяем данные по оси Y. Поворот вверх.
      // if (sensor.axisX <= 2 && sensor.axisY <= MIN_VALUE){Choice = 2;}              // Проверяем данные по оси Y. Поворот вниз.
      yz--;                                                                           // Координаты формирования змейки при движении влево. Увеличиваем координату Y на количество пройденных квадратиков.
      break;                                                                        //
    //
    case 2: //низ
      grad = 3;
      if (valBtnR == 1)
      { valBtnR = 0;
        Choice = 3;
      }
      if (valBtnL == 1)
      { valBtnL = 0;
        Choice = 4;
      }// Движение вниз.
      // if (sensor.axisY >= -2 && sensor.axisX >= MAX_VALUE){Choice = 4;}             // Проверяем данные по оси X. Поворот вправо.
      // if (sensor.axisY >= -2 && sensor.axisX <= MIN_VALUE){Choice = 3;}             // Проверяем данные по оси X. Поворот влево.
      xz--;                                                                          // Координаты формирования змейки при движении влево. Увеличиваем координату X на количество пройденных квадратиков.
      break;                                                                        //
    //
    case 1:  //верх
      grad = 1;
      if (valBtnL == 1)
      { valBtnL = 0;
        Choice = 4;
      }// Движение вверх.
      if (valBtnR == 1)
      { valBtnR = 0;
        Choice = 3;
      }
      //if (sensor.axisY <= 2 && sensor.axisX >= MAX_VALUE){Choice = 4;}              // Проверяем данные по оси X. Поворот вправо.
      //  if (sensor.axisY <= 2 && sensor.axisX <= MIN_VALUE){Choice = 3;}              // Проверяем данные по оси X. Поворот влево.
      xz++;                                                                          // Координаты формирования змейки при движении влево. Уменьшаем координату X на количество пройденных квадратиков.
      break;                                                                        //
  }                                                                                 //
}

void ShowSnake()    //завершающее шоу                                                                  //
{ nTail = nTail - 3;                                                                              //
  ycor = 6;                                                                           // Присваиваем дополнительное координате значение 6. С 6 Y-координаты строим змейку столбцами по 5 элементов.
  for (int k = 1; k <= 100; k++)                                                      // Цикл вывода змейки на экран.
  { //
    if (nTail > 5)                                                                    // Сравниваем количество элементов с 5. Столбцы формируемые снизу вверх. Нечетные столбцы.
    { // Если больше 5.
      aTail = 5;                                                                      // Присваиваем дополнительной переменной значение 5.
      for (int i = 56; i >= 56 - aTail * 4; i = i - 5)                                // Цикл формирования и вывода змейки по координатам, начиная с X = 56 до X = 36 с шагом 5.
      { myGLCD.setColor(VGA_RED);
        myGLCD.drawBitmap (ycor * 7, i * 7, 30, 30, apple);
        // myGLCD.drawRect (ycor*7, i*7, (ycor+3)*7, (i+3)*7);                              // Вывод змейки квадратами начиная с координат Y = 6, X = 56, Y = 9, X = 59 до координат Y = 6, X = 36 Y = 9, X = 39. Значения Y-координаты указаны для первого столбца.
        delay(200);                                                                   // Задержка 200 мс.
      }                                                                               //
      nTail = nTail - 5;                                                              // Вычитаем из количества элементов в змейке 5. Для определения количества выводимых столбцов.
    }                                                                                 //
    else                                                                              // Если меньше 5.
    { //
      aTail = nTail;                                                                  // Присваиваем оставшееся количество элементов дополнительной переменной.
      for (int i = 56; i >= 56 - aTail * 4; i = i - 5)                                // Цикл формирования и вывода змейки по координатам с шагом 5, начиная с X = 56 до X-координаты соответствующая значению количества оставшихся элементов змейки.
      { myGLCD.setColor(VGA_YELLOW);                                                                            //
        myGLCD.drawBitmap (ycor * 7, i * 7, 30, 30, apple);                                                                       //
        // Вывод змейки квадратами начиная с координат Y = 6, X = 56, Y = 9, X = 59 до координат Y = 6, X = 36 Y = 9, X = 39. Значения Y-координаты указаны для первого столбца.
        delay(200);                                                                   // Задержка 200 мс.
      }                                                                               //
      delay (1000);
      for (int i = 0; i < 10; i++)
      { Keys();
        delay (1000);
      }
      return zmeyka();
    }                                                                                 //
    if (nTail > 5)                                                                    // Сравниваем количество элементов с 5. Столбцы формируемые сверху вниз. Четные столбцы.
    { // Если больше 5.
      aTail = 5;                                                                      // Присваиваем дополнительной переменной значение 5.
      for (int i = 36; i <= 36 + aTail * 4; i = i + 5)                                // Цикл формирования и вывода змейки по координатам, начиная с X = 36 до X = 56 с шагом 5.
      { myGLCD.setColor(VGA_YELLOW);                                                                            //
        //
        myGLCD.drawBitmap ((ycor + 5) * 7, i * 7, 30, 30, apple); //                           // Вывод змейки квадратами начиная с координат Y = 11, X = 36, Y = 14, X = 39 до координат Y = 11, X = 56 Y = 14, X = 59. Значения Y-координаты указаны для первого столбца.
        delay(200);                                                                   // Задержка 200 мс.
      }                                                                               //
      nTail = nTail - 5;                                                              // Вычитаем из количества элементов в змейке 5. Для определения количества выводимых столбцов.
    }                                                                                 //
    else                                                                              // Если меньше 5.
    { //
      aTail = nTail;                                                                  // Присваиваем оставшееся количество элементов дополнительной переменной.
      for (int i = 36; i <= 36 + aTail * 4; i = i + 5)                                // Цикл формирования и вывода змейки по координатам с шагом 5, начиная с X = 36 до X-координаты соответствующая значению количества оставшихся элементов змейки.
      { myGLCD.setColor(VGA_RED);
        myGLCD.drawBitmap ((ycor + 5) * 7, i * 7, 30, 30, apple); //
        // myGLCD.drawRect (ycor+5, i, ycor+8, i+3);                            // Вывод змейки квадратами начиная с координат Y = 11, X = 36, Y = 14, X = 39 до координат Y = 11, X = 56 Y = 14, X = 59. Значения Y-координаты указаны для первого столбца.
        delay(200);                                                                   // Задержка 200 мс.
      }
      for (int i = 0; i < 10; i++)
      { Keys();
        delay (1000);
      }

      return zmeyka();                                                                 // Возвращаемся в функцию Setup().
    }                                                                                 //
    ycor = ycor + 10;                                                                 // Увеличиваем дополнительную Y-координату на значение 10. Строим новый ряд столбцов.
  }                                                                                   //
}

// Функция завершения игры.
void GameOver()                                                                       //
{ //
  myGLCD.setColor(67, 200, 81);
  myGLCD.fillRect (2, 2, 479, 479);                                                                   // Чистим экран.
  myGLCD.setBackColor(VGA_TRANSPARENT);
  myGLCD.setColor(VGA_WHITE);                                                       // Указываем шрифт который требуется использовать для вывода цифр и текста.
  myGLCD.print("GAME OVER", 200, 100);                                             // Выводим текст по центру 25 строки.
  //  myGLCD.print("SCORE - ", CENTER, 150);                                               // Выводим текст 25 столбца 20 строки.
  myGLCD.printNumI(nTail - 3, 580, 389);                                                   // Выводим переменную 95 столбца 40 строки.
  // Разрешаем автоматический вывод данных.
}

void Keys()
{
  but();
  //***********  T  O  U  C  H  ********************
  if (myTouch.dataAvailable())
  {
    myTouch.read();
    xt = myTouch.getX();
    yt = myTouch.getY();
    // Serial.print("xt=");
    // Serial.println(xt);
    //  Serial.print("yt=");
    //   Serial.println(yt);
    if ((xt >= 490) && (xt <= 550)) // Upper row
    {
      if ((yt >= 5) && (yt <= 50)) // Button: 1
      {
        valBtnPause = 1;
        myGLCD.setColor(VGA_WHITE);
        myGLCD.drawLine(503, 29, 503 + 60, 29);
        myGLCD.drawLine(503, 30, 503 + 60, 30);
        //myGLCD.drawLine(480, 45,480+60, 45);
      }
      if ((yt >= 220) && (yt <= 255)) // Button: 1
      {
        valBtnL = 1; //LEFT
        myGLCD.setColor(VGA_WHITE);
        myGLCD.drawLine(503, 239, 503 + 60, 239);
        myGLCD.drawLine(503, 240, 503 + 60, 240);
      }
    }
    if ((xt >= 560) && (xt <= 640)) // Upper row
    {
      if ((yt >= 110) && (yt <= 140)) // Button: 1
      {
        valBtnT = 1; //UP
        myGLCD.setColor(VGA_WHITE);
        myGLCD.drawLine(610, 132, 610 + 60, 132);
        myGLCD.drawLine(610, 133, 610 + 60, 133);
      }
      if ((yt >= 320) && (yt <= 358)) // Button: 1
      {
        valBtnD = 1; //DOWN
        myGLCD.setColor(VGA_WHITE);
        myGLCD.drawLine(610, 344, 610 + 60, 344);
        myGLCD.drawLine(610, 345, 610 + 60, 345);
      }
    }
    if ((xt >= 700) && (xt <= 780)) // Upper row
    {
      if ((yt >= 220) && (yt <= 255)) // Button: 1
      {
        valBtnR = 1; //RIGHT
        myGLCD.setColor(VGA_WHITE);
        myGLCD.drawLine(713, 239, 713 + 60, 239);
        myGLCD.drawLine(713, 240, 713 + 60, 240);
      }

    }
    if ((xt >= 750) && (xt <= 790)) // Upper row
    {
      if ((yt >= 10) && (yt <= 60)) // Button: 1
      {
        exit_menu = 1; //ВЫХОД
      }

    }
  }
  if (valBtnPause == 1)
  { valBtnPause = 0;
    myGLCD.setColor(VGA_RED);
    // myGLCD.setBackColor (98,65,32);

    myGLCD.setBackColor(VGA_TRANSPARENT);
    // myGLCD.setColor(98,65,32);
    myGLCD.print("P A U S E", 140, 100);

    delay(3000);
    while (1)
    { //delay(500);
      but();
      if (myTouch.dataAvailable())
      {
        myTouch.read();
        xt = myTouch.getX();
        yt = myTouch.getY();
        valBtnT = 1;
      }
      if (valBtnL || valBtnR || valBtnT || valBtnD)
      { valBtnPause = 0;
        myGLCD.setColor(67, 200, 81);
        // myGLCD.print("         ",(MaxX*razmer/2)+SmeX-110,158);
        myGLCD.print("P A U S E", 140, 100);
        //  myGLCD.setColor(VGA_BLUE);
        // myGLCD.drawLine(480,29,480+60, 29);
        //  myGLCD.drawLine(480,30,480+60, 30);
        delay(100);
        break;
      }
    }
  }
  if (exit_menu == 1)
  { exit_menu = 0;
    loop();
  }
}
