Реализация змейки

arduino not my
arduino not my аватар
Offline
Зарегистрирован: 28.10.2020

Здравствуйте, знатоки. Помогите, пожалуйста, в реализации змейки.Библиотека для дисплея от adafruit.Отработка кнопок GyverButton.  Если что - это кусок скетча для игровой мини консоли с несколькими играми. Сделал движение змеи, условия игры, яблоки,счет и тд.А как ей движение то задать?Заранее спасибо.

void snakeEngine() {
  uint32_t timer;             
  byte headX = random(5, 31);  
  byte headY = random(2, 15);
  byte snakeLenght = 1;
  byte snakeTailX[snakeLenght];          
  byte snakeTailY[snakeLenght];
  bool appleEat = true;
  byte appleX;
  byte appleY;
  byte dir;   // 1 - F 2 - B 3 - L 4 - R
  long vel = 250;
  bool lose = false;
  byte i;
  while (lose == false) {
    if (appleEat == true) {
      appleX = random(31);
      appleY = random(15);
      appleEat = false;
    }

    if (L.isClick()) {
      if (dir != 4) {
        dir = 3;
      }
    }
    if (R.isClick()) {
      if (dir != 3) {
        dir = 4;
      }
    }
    if (UP.isClick()) {
      if (dir != 2) {
        dir = 1;
      }
    }
    if (DOWN.isClick()) {
      if (dir != 1) {
        dir = 2;
      }
    }

    if (millis() - timer >= vel) {
      timer = millis();
      snakeTailX[1] = headX + 4;
      snakeTailY[1] = headY + 4;
      switch (dir) {
        case 1:   //FORWARD
          headY = constrain(headY - 1, 0, 15);
          break;
        case 2:   //BACKWARD
          headY = constrain(headY + 1, 0, 15);
          break;
        case 3:  //LEFT
          headX = constrain(headX - 1, 0, 31);
          break;
        case 4:  //RIGHT
          headX = constrain(headX + 1, 0, 31);
          break;
      }
    }

    if (DOWN.isHold() or UP.isHold() or L.isHold() or R.isHold()) {
      vel = 50;
    }

    if (DOWN.isRelease() or UP.isRelease() or L.isRelease() or R.isRelease()) {
      vel = 250;
    }

    if (headX == appleX and headY == appleY) {
      snakeLenght++;
      appleEat = true;
    }

    if (headX == 0 or headX == 31 or headY == 0 or headY == 15) {
      display.setTextSize(2);
      display.setCursor(15, 26);
      display.print("YOU LOSE");
      display.display();
      delay(2000);
      display.clearDisplay();
      display.setTextSize(1);
      display.display();
      break;
    }

    if (S.isClick()) {
      break;
    }

    display.fillRect(headX * 4,  headY * 4, 4, 4, WHITE);
    display.fillRect(appleX * 4, appleY * 4, 4, 4, WHITE);
    display.fillRect(snakeTailX[i] * 4, snakeTailY[i] * 4, 4, 4, WHITE);
    display.setCursor(0, 0);
    display.print(snakeLenght);
    display.display();
    display.clearDisplay();

  }
}

 

Morroc
Offline
Зарегистрирован: 24.10.2016

arduino not my пишет:

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

Вы уж определитесь сделали или не сделали движение. В коде попытка сделать есть. В чем проблема то ?

b707
Offline
Зарегистрирован: 26.05.2017

Morroc пишет:

Вы уж определитесь сделали или не сделали движение.

может верхний код не ТС, он его где-то списал?

arduino not my
arduino not my аватар
Offline
Зарегистрирован: 28.10.2020

Простите, не движение, а длинну змейки

Morroc
Offline
Зарегистрирован: 24.10.2016

b707 пишет:

может верхний код не ТС, он его где-то списал?

Не просто списал, но и творчески доработал )

arduino not my пишет:

Простите, не движение, а длинну змейки

Почему у вас в 45 и 46 в массив хвоста заносятся координаты головы +4 ? Что такое i в строке 94 ? Башка змеи разве не двигается ? Что на экране видно ?

arduino not my
arduino not my аватар
Offline
Зарегистрирован: 28.10.2020

Та не списал я, это первый мой более менее сложный скетч, так что сильно не пинайте=).С строках 45 и 46 я пытался хранить в массиве все элементы змейки кроме головы, а потом выводить их через for.Нумерацию в массиве я начал с 1, чтобы можно было выводить хвост змеи через переменную длинны змеи.Число 4 это волшебное число в этом коде.Дело в том, что я сделал игровое поле как сетку 16 на 32. А дисплей 128 на 64...

Morroc
Offline
Зарегистрирован: 24.10.2016

Это оно в конце скетча волшебное когда на экран выводите, в 45 и 46 оно не нужно, хотите отступ от края экрана - сделайте это когда рисуете. Нумерация элементов по длине хвоста - это ладно, но единственное место, где вы работаете с хвостом, кроме 45 и 46 - это 94, в ней у вас переменная i, если вы сможете объяснить что это и зачем - я прям удивлюсь.

Вот над этим подумайте пока:

Делать clearDisplay() постоянно хреновый вариант - у вас будет моргать дисплей и, возможно, тормозить. Координаты всех объектов вы знаете - башку рисуйте, конец хвоста стирайте.

Массив хвоста по вашей задумке растет с удлинением змеи. Вы запоминаете координаты башки перед её движением так snakeTailX[1] = headX + 4; snakeTailY[1] = headY + 4; теперь вопрос - на следующем шаге у вас координаты башки опять попадут в [1], но вы ничего не делаете с массивом, т.е. просто перезатираете координаты в [1]. Чего то явно не хватает... ммм ? 

( про гайверовские кнопки ничего не скажу, просто надеюсь, что оно работает :) )

и чего у вас скетч какой то не ардуинский ? скиньте целиком
arduino not my
arduino not my аватар
Offline
Зарегистрирован: 28.10.2020

Это олед дисплей, и на нем это выглядит нормально, не мерцает.Весь скетч целиком огромный, а это лишь функция игры, которую я вызываю.Про библиотеку гайвера - это довольно удобно, и да , это работает.

Morroc
Offline
Зарегистрирован: 24.10.2016

arduino not my пишет:

Это олед дисплей, и на нем это выглядит нормально, не мерцает.

Это довольно странно, возможно связано с небольшой областью отрисовки, но советую проверить вариант без cleardisplay. Если бы не мерцало я бы так тоже делал )

Вы так и не написали у вас башка змеи перемещается ? Если нет - могут быть еще проблемы не связанные с массивом хвоста.

arduino not my
arduino not my аватар
Offline
Зарегистрирован: 28.10.2020

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

void snakeEngine() {
  uint32_t timer;
  byte snakeLenght = 1;
  byte snakeX[50];
  byte snakeY[50];
  bool appleEat = true;
  byte appleX;
  byte appleY;
  byte dir;   // 1 - F 2 - B 3 - L 4 - R
  long vel = 150;
  bool lose = false;
  int i;

  snakeX[0] = 5;
  snakeY[0] = 5;
  while (lose == false) {
    if (appleEat == true) {
      appleX = random(31);
      appleY = random(15);
      appleEat = false;
    }

    if (L.isClick()) {
      if (dir != 4) {
        dir = 3;
      }
    }
    if (R.isClick()) {
      if (dir != 3) {
        dir = 4;
      }
    }
    if (UP.isClick()) {
      if (dir != 2) {
        dir = 1;
      }
    }
    if (DOWN.isClick()) {
      if (dir != 1) {
        dir = 2;
      }
    }

    for (int i = snakeLenght; i > 0; i--) {
      snakeX[i] = snakeX[i - 1];
      snakeY[i] = snakeY[i - 1];
    }

    if (millis() - timer >= vel) {
      timer = millis();
      switch (dir) {
        case 1:   //FORWARD
          snakeY[0] = constrain(snakeY[0] - 1, 0, 15);
          break;
        case 2:   //BACKWARD
          snakeY[0] = constrain(snakeY[0] + 1, 0, 15);
          break;
        case 3:  //LEFT
          snakeX[0] = constrain(snakeX[0] - 1, 0, 31);
          break;
        case 4:  //RIGHT
          snakeX[0] = constrain(snakeX[0] + 1, 0, 31);
          break;
      }
    }

    if (DOWN.isHold() or UP.isHold() or L.isHold() or R.isHold()) {
      vel = 50;
    }

    if (DOWN.isRelease() or UP.isRelease() or L.isRelease() or R.isRelease()) {
      vel = 250;
    }

    if (snakeX[0] == appleX and snakeY[0] == appleY) {
      snakeLenght++;
      appleEat = true;
    }

    if (snakeX[0] == 0 or snakeX[0] == 31 or snakeY[0] == 0 or snakeY[0] == 15) {
      display.setTextSize(2);
      display.setCursor(15, 26);
      display.print("YOU LOSE");
      display.display();
      delay(2000);
      display.clearDisplay();
      display.setTextSize(1);
      display.display();
      break;
    }

    if (S.isClick()) {
      break;
    }

    display.fillRect(appleX * 4, appleY * 4, 4, 4, WHITE);
    for (i = 1; i < snakeLenght; i++) {
      display.fillRect(snakeX[i] * 4, snakeY[i] * 4, 4, 4, WHITE);
    }
    display.fillRect(snakeX[0] * 4, snakeY[0] * 4, 4, 4, WHITE);
    display.setCursor(0, 0);
    display.print(snakeLenght);
    display.display();
    display.clearDisplay();

  }
}

 

Morroc
Offline
Зарегистрирован: 24.10.2016

Теперь похоже на правду. Какие то проблемы остались ?

arduino not my
arduino not my аватар
Offline
Зарегистрирован: 28.10.2020

Спасибо за помощь, теперь это полноценная змейка.