Flappy bird на ардуино.

Тема в разделе "Arduino & Shields", создана пользователем Sanagin, 11 дек 2019.

  1. Sanagin

    Sanagin Нерд

    Просьба помочь отредактировать код, вместо джойстика должна быть кнопка. Пин S кнопки - это 7
    Пины матрицы такие же*
    Вот источник кода: http://wiki.amperka.ru/arduino-projects:arduino-flappy-bird
    Код (C++):
    // библиотека для работы с RGB-матрицей
    #include <Adafruit_NeoPixel.h>
    // номер пина, к которому подключена RGB-матрица
    #define MATRIX_C_PIN    4
    #define MATRIX_F_PIN    10
    // количество светодиодов в матрице
    #define LED_COUNT 16
    // зерно для генератора случайных чисел
    #define ANALOG_PIN_FOR_RND  A3
    // максимальная яркость матрицы от 0 до 255
    #define BRIGHT 10
    // даём разумные имена пинам, к которым подключён джойстик
    #define X  A5
    #define Y  A4
    #define Z  2
    // создаём объект класса Adafruit_NeoPixel
    Adafruit_NeoPixel matrix [] = {Adafruit_NeoPixel(LED_COUNT, MATRIX_C_PIN, NEO_GRB + NEO_KHZ800),
                                   Adafruit_NeoPixel(LED_COUNT, MATRIX_F_PIN, NEO_GRB + NEO_KHZ800)
                                  };
    // создаем структуру для размещения в ней цветов
    struct Light
    {
      uint32_t Y = 0xffff00;
      uint32_t G = 0x00ff00;
      uint32_t B = 0x0000ff;
    };
    // создаем структуру для размещения в ней параметров счета
    struct Store
    {
      int value;
      bool flag;
    };
    // создаем структуру для размещения в ней параметров игровых объектов
    struct GameObjects
    {
      int x;
      int y;
      bool flag;
    };
    // создаем объект структуры Light
    Light light;
    // создаем объект структуры Store
    Store store;
    // создаем объекты структуры GameObjects: игрока и стену
    GameObjects player, wall;
    // создаем объект класса long для хранения времени
    unsigned long timeOfGravity = 0;
    // создаем счетчик, по которому действует гравитация
    int gravity = 500;
    // создаем объект класса long для хранения времени
    unsigned long timeOfSide = 0;
    // создаем счетчик, который определяет "скорость" стены
    int side;
    void setup() {
      // инициализируем последовательность случайных чисел
      randomSeed(analogRead(ANALOG_PIN_FOR_RND));
      // инициализируем все матрицы
      for (int i = 0; i < sizeof(matrix) / sizeof(Adafruit_NeoPixel); i++) {
        matrix[i].begin();
        matrix[i].setBrightness(10);
      }
      // открываем последовательный порт
      Serial.begin(9600);
      // очищаем матрицы
      draw_clear ();
    }
    void loop() {
      // запускаем функцию предстартовой подготовки
      at_the_start();
      // пока флаг счета опущен, игра не начнется
      // когда же он поднят, то не игра закончится
      while (store.flag) {
        // очищаем матрицы
        draw_clear ();
        // отслеживаем перемещение стены
        wall_move ();
        // рисуем стену на матрицах
        wall_draw();
        // считываем движения джойстика
        player_move ();
        // рисуем на матрице положение игрока
        draw_point(player.x, player.y, light.Y);
        // проверяем, не вышел ли игрок за пределы поля
        if ( player.y < 0 || player.y >= 8) {
          // если вышел, то воспроизводим проигрыш
          game_over();
        }
        // когда стена и игрок сравняются по x...
        if (player.x == wall.x ) {
          // ...проверяем, не врезался ли игрок в стену
          if (player.y != wall.y && player.y != wall.y + 1) {
            // если врезался, то воспроизводим проигрыш
            game_over();
          }
          // ... если игра все же не проиграна то однократно выполняем условие победы
          if (wall.flag) {
            // увеличиваем счет
            store.value ++;
            // увеличиваем "скорость"
            side -= side / 10;
            // опускаем флаг однократного выполнения
            wall.flag = false;
          }
        } else {
          // держим флаг поднятым до тех пор, пока не наступит победа
          wall.flag = true;
        }
      }
    }
    // функция приготовления к игре
    void at_the_start() {
      // очищаем матрицы
      draw_clear ();
      // задаем начальное значение счетчика "скорости" стены
      side = 1500;
      // обнуляем значение счета и держим флаг счетчика опущенным
      store = { 0, false};
      // задаем начальное значение координат игрока
      player = {3, 4, true};
      // задаем начальное значение координат стены
      wall = { -1, random(0, 6), true};
      // считываем движения джойстика
      player_move ();
      // рисуем на матрице положение игрока
      draw_point(player.x, player.y, light.Y);
      delay (250);
    }
    // функция окончания игры
    void game_over() {
      // очищаем матрицы
      draw_clear ();
      // заливаем матрицы синим цветом
      draw_pouring (light.B);
      // выводим счет в Serial port
      Serial.print ("Your store: ");
      Serial.println (store.value);
      // опускаем флаг счета
      store.flag = false;
      // инициализируем последовательность случайных чисел
      randomSeed(analogRead(ANALOG_PIN_FOR_RND));
      delay (250);
    }
    // функция движения игрока
    void player_move () {
      int y, z;
      // считываем текущее значение джойстика по Y
      y = analogRead(Y);
      if (y < 100 && player.flag) {
        player.y ++;
        player.flag = false;
      }
      if (y > 924 && player.flag) {
        player.y --;
        player.flag = false;
      }
      if (100 < y && y < 924) {
        player.flag = true;
      }
      // создаем постоянную простую гравитацию
      if (millis() - timeOfGravity > gravity) {
        player.y --;
        timeOfGravity = millis();
      }
      // считываем текущее значение джойстика по Z
      z = digitalRead(Z);
      if (z == 1 && store.flag == false) {
        store.flag = true;
      }
    }
    // функция движения стены
    void wall_move () {
      // запускаем таймер, по которому стена будет перемещаться
      if (millis() - timeOfSide > side) {
        // если стена за пределами видимости игрока
        if (wall.x >= 4) {
          // то изменяем ее и перемещаем в начало
          wall.x = 0;
          wall.y = random(0, 7);
        } else {
          // если нет, то двигаем ее на игрока
          wall.x++;
        }
        timeOfSide = millis();
      }
    }
    // функция рисования препятствия
    void wall_draw () {
      // проверяем координату стены, в зависимости от этого рисуем одну или 2 линии
      switch (wall.y) {
        case 0: {
            draw_line(wall.x, 2, wall.x, 7, light.G);
            break;
          }
        case 6: {
            draw_line(wall.x, 0, wall.x, 5, light.G);
            break;
          }
        default : {
            draw_line(wall.x, 0, wall.x, wall.y - 1, light.G);
            draw_line(wall.x, wall.y + 2, wall.x, 7, light.G);
            break;
          }
      }
    }
    // функция для перевода координат в № матрицы
    int nHelper (int x, int y) {
      return y / 4 + ((x / 4) * 2);
    }
    // функция для перевода координат в № светодиода
    int mHelper(int x, int y) {
      switch (nHelper (x, y)) {
        case 0: {
            return {y * 4 + x};
            break;
          }
        case 1: {
            return {abs (y - 8) * 4 - x - 1};
            break;
          }
      }
    }
    // функция для рисования линий по алгоритму Брезенхэма
    void draw_line(int x1, int y1, int x2, int y2, uint32_t RGB) {
      const int deltaX = abs(x2 - x1);
      const int deltaY = abs(y2 - y1);
      const int signX = x1 < x2 ? 1 : -1;
      const int signY = y1 < y2 ? 1 : -1;
      int error = deltaX - deltaY;
      matrix[nHelper(x2, y2)].setPixelColor(mHelper(x2, y2), RGB);
      while (x1 != x2 || y1 != y2)
      {
        matrix[nHelper(x1, y1)].setPixelColor(mHelper(x1, y1), RGB);
        const int error2 = error * 2;
        if (error2 > -deltaY)
        {
          error -= deltaY;
          x1 += signX;
        }
        if (error2 < deltaX)
        {
          error += deltaX;
          y1 += signY;
        }
      }
      for (int i = 0; i < sizeof(matrix) / sizeof(Adafruit_NeoPixel); i++) {
        matrix[i].show();
      }
    }
    // функция для рисования сплошной заливкой
    void draw_pouring (uint32_t RGB) {
      for (int i = 0; i < sizeof(matrix) / sizeof(Adafruit_NeoPixel); i++) {
        for (int j = 0; j < LED_COUNT; j++) {
          matrix[i].setPixelColor(j, RGB);
          matrix[i].show();
        }
      }
    }
    // функция для рисования точки
    void draw_point (int x, int y, uint32_t RGB) {
      matrix[nHelper(x, y)].setPixelColor(mHelper(x, y), RGB);
      matrix[nHelper(x, y)].show();
    }
    // функция для очистки матриц
    void draw_clear () {
      for (int i = 0; i < sizeof(matrix) / sizeof(Adafruit_NeoPixel); i++) {
        matrix[i].clear();
        matrix[i].show();
      }
    }
     
    Последнее редактирование: 11 дек 2019
  2. NikitOS

    NikitOS Король шутов Администратор

    Обитатели сего форума делают что-то только за денежку. Бесплатно только пнуть в нужную сторону могут
    Хотя я не понял, что там редактировать надо...
     
  3. Sanagin

    Sanagin Нерд

    Джойстик заменить на кнопку, у них ведь разный "функционал"
     
  4. NikitOS

    NikitOS Король шутов Администратор

    Там изменить надо всего три-четыре строки. В чем проблема-то?
     
  5. Sanagin

    Sanagin Нерд

    Для меня это проблема, я не очень хорошо разбираюсь в этом, и если можете помочь, прошу вас помочь
     
  6. Asper Daffy

    Asper Daffy Иксперд

    Проблема, это когда шеф тебя с евойной женой застукал. А тут какие проблемы? зашёл в "закажу проект", объяснил толком чего надо, заплатил, да получил готовое.
     
    b707 и DetSimen нравится это.