Неизвестная ошибка в коде игры

Тема в разделе "Arduino & Shields", создана пользователем Delofon, 11 фев 2018.

  1. Delofon

    Delofon Нуб

    Создаю игру на Arduino UNO с LCD 16x2, но у меня не работает функция которая отвечает за прорисовку объектов. Заранее спасибо за помощь. Код функции:

    Код (C++):
    void draw()
    {
      lcd.clear();
      for(char i = 0; i < pos[32-1];i++)
      {
        if(pos[i] == 1 && i < 16)
        {
          lcd.setCursor(i, 0);
          lcd.write((uint8_t)0);
        }
        else if(pos[i] == 2 && i < 16)
        {
          lcd.setCursor(i, 0);
          lcd.write((uint8_t)1);
        }
        else if(pos[i] == 3 && i < 16)
        {
          lcd.setCursor(i, 0);
          lcd.write((uint8_t)2);
        }
        else if(pos[i] == 4 && i < 16)
        {
          lcd.setCursor(i, 0);
          lcd.write((uint8_t)3);
        }
        else if(pos[i] == 1 && i > 15)
        {
          lcd.setCursor(i-16, 1);
          lcd.write((uint8_t)0);
        }
        else if(pos[i] == 2 && i > 15)
        {
          lcd.setCursor(i-16, 1);
          lcd.write((uint8_t)1);
        }
        else if(pos[i] == 3 && i > 15)
        {
          lcd.setCursor(i-16, 1);
          lcd.write((uint8_t)2);
        }
        else if(pos[i] == 4 && i > 15)
        {
          lcd.setCursor(i-16, 1);
          lcd.write((uint8_t)3);
        }
      }
    }
     
  2. ostrov

    ostrov Гуру

    В чем именно ошибка? Или вы хотите чтобы мы все собрали и проверили, к тому же дописав программу до рабочего вида?
     
  3. Delofon

    Delofon Нуб

    Это не ошибка компиляции. Функция просто отказывается работать, и я не понимаю почему.
     
  4. b707

    b707 Гуру

    а вот так не проще будет? :)
    (ошибки не искал, просто переписал ваш некрасивый код)
    Код (C++):
    void draw()
    {
      lcd.clear();
      for(char i = 0; i < pos[32-1];i++)
      {
        if ( (pos[i] >0) && (pos[i] <5))
         {if ( i<16 ) lcd.setCursor(i, 0);
          else lcd.setCursor(i-16, 1);
          lcd.write((uint8_t)((pos[i] - 1));
         }
    }
    На тему ошибок - напишите, что код должен делать и что он у вас реально делает.
     
  5. ostrov

    ostrov Гуру

    Что значит отказывается работать? Пишет фак на экране? Почему надо клещами вытаскивать информацию?
     
  6. Delofon

    Delofon Нуб

    Функция должна "напечатать" на экране объекты исходя из переменных которые отвечают за позиции объектов.
    На самом деле, функция просто ничего не делает. На LCD не появляются желаемые объекты.
     
  7. ostrov

    ostrov Гуру

    Стесняюсь спросить, он хоть правильно подключен? Тестовые надписи выводит?
     
  8. Delofon

    Delofon Нуб

    Да, выводит
     
  9. b707

    b707 Гуру

    что-то я в этом коде не вижу никакого вывода "обьектов" на экран. Вижу, что с помощью оператора lcd.write() вы пытаетесь вывести на экран символы с кодами от 0 до 4. Все эти символы - непечатаемые, то есть LCD. скорее всего, не умеет их выводить. Вместо байтов 0-4 вам надо выводить на экран символы '0' - '4' - а это совсем не одно и тоже.
     
  10. Delofon

    Delofon Нуб

    печатаемые, это точно. для этого есть оператор lcd.createChar(номер, байт)
    Код (C++):
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(/*пины*/);
    byte Player[8] =
    {
      B00000,
      B11110,
      B00100,
      B01111,
      B01111,
      B00100,
      B11110,
      B00000
    };
    void setup()
    {
    lcd.createChar(0, Player);
    //...
    }
    void loop()
    {
        //...
    }
     
  11. b707

    b707 Гуру

    причем здесь этот код, и как он связан с вашей функцией draw() ?
    Покажите весь код скетча, а не какие-то кусочки.
     
  12. Delofon

    Delofon Нуб

    Код (C++):
    #include <LiquidCrystal.h>
    #define goLeft 7
    #define goRight 6
    #define shoot 5
    LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
    int playerPos = 0;
    char pos[32];
    int what2;
    byte Player[8] =
    {
      B00000,
      B11110,
      B00100,
      B01111,
      B01111,
      B00100,
      B11110,
      B00000
    };
    byte playerLaser[8] =
    {
      B00000,
      B00000,
      B00000,
      B11111,
      B11111,
      B00000,
      B00000,
      B00000
    };
    byte Invader[8] =
    {
      B00111,
      B01001,
      B00011,
      B01101,
      B01101,
      B00011,
      B01001,
      B00111
    };
    byte Asteroid[8] =
    {
      B00010,
      B00110,
      B01110,
      B01110,
      B01110,
      B01100,
      B00100,
      B00000
    };
    void setup()
    {
      lcd.createChar(0, Player);
      lcd.createChar(1, playerLaser);
      lcd.createChar(2, Invader);
      lcd.createChar(3, Asteroid);
      lcd.begin(16, 2);
    }

    void loop() //P
    {
      if(digitalRead(goLeft) == HIGH)
      {
        pos[17] = 0;
        playerPos = 0;
      }
      if(digitalRead(goRight) == HIGH)
      {
        playerPos = 17;
        pos[16] = 0;
      }
      if(digitalRead(shoot) == HIGH && playerPos == 0)
      {
        shootLaser(0);
      }
      if(digitalRead(shoot) == HIGH && playerPos == 1)
      {
        shootLaser(1);
      }
      gameTick();
      delay(1500);
    }
    void gameTick()
    {
      pos[playerPos] = 1;
      int newInvader = random(0,2);
      int newAsteroid = random(0,3);
      spawnInvader(newInvader);
      spawnAsteroid(newAsteroid);
      moveGame();
      draw();
      delay(1500);
      moveGame();
      draw();
      if(millis() == 60000)
      {
        heyYou();
      }
    }
    void moveGame() //Функция в разработке
    {
      for(int x = 0; x < pos[32-1]; x++)
      {
     
      }
      //Laser need to be moved. Can be bugged.
      updateLaser();
    }
    void shootLaser(int whereplayeris) //Функция в разработке
    {
      lcd.setCursor(1, playerPos);
      int what = playerPos;
      what2 = 1;
      lcd.write((uint8_t)1);
    }
    void updateLaser() //Функция в разработке
    {

    }
    void spawnInvader(int invaderNewPos)
    {
      if(invaderNewPos == 2)
      {
        delay(1500);
        loop();
      }
      else if(invaderNewPos == 0)
      {
        pos[16] = 3;
      }
      else
      {
        pos[32] = 3;
      }
    }
    void spawnAsteroid(int asteroidNewPos)
    {
      if(asteroidNewPos == 2)
      {
        delay(1500);
        loop();
      }
      else if(asteroidNewPos == 0)
      {
        pos[16] = 4;
      }
      else if(asteroidNewPos == 1)
      {
        pos[32] = 4;
      }
      else
      {
        pos[16] = 4;
        pos[32] = 4;
      }
    }
    void draw()
    {
      lcd.clear();
      for(char i = 0; i < pos[32-1];i++)
      {
        if(pos[i] == 1 && i < 16)
        {
          lcd.setCursor(i, 0);
          lcd.write((uint8_t)0);
        }
        else if(pos[i] == 2 && i < 16)
        {
          lcd.setCursor(i, 0);
          lcd.write((uint8_t)1);
        }
        else if(pos[i] == 3 && i < 16)
        {
          lcd.setCursor(i, 0);
          lcd.write((uint8_t)2);
        }
        else if(pos[i] == 4 && i < 16)
        {
          lcd.setCursor(i, 0);
          lcd.write((uint8_t)3);
        }
        else if(pos[i] == 1 && i > 15)
        {
          lcd.setCursor(i-16, 1);
          lcd.write((uint8_t)0);
        }
        else if(pos[i] == 2 && i > 15)
        {
          lcd.setCursor(i-16, 1);
          lcd.write((uint8_t)1);
        }
        else if(pos[i] == 3 && i > 15)
        {
          lcd.setCursor(i-16, 1);
          lcd.write((uint8_t)2);
        }
        else if(pos[i] == 4 && i > 15)
        {
          lcd.setCursor(i-16, 1);
          lcd.write((uint8_t)3);
        }
      }
    }
    void heyYou() //G and P ? :O
    {
      spawnInvader(0);
      spawnInvader(1);
      delay(500);
      moveGame();
      draw();
      delay(500);
      lcd.clear();
      lcd.print("The end :p");
      lcd.setCursor(0, 1);
      lcd.print("RST for restart");
    }
     
  13. b707

    b707 Гуру

    А что, мой код draw() из сообщения #4 вас чем-то не устраивает? Делает ровно то же самое, но примерно впятеро короче вашего. Ну как хотите.
    Для тестирования - замените в своем скетче функцию draw вот такой функцией и скажете, что получилось

    Код (C++):


    void draw()
    {
      lcd.clear();
      for(char i = 0; i < pos[32-1];i++)
      {
        if ( (pos[i] >0) && (pos[i] <5))
         {if ( i<16 ) lcd.setCursor(i, 0);
          else lcd.setCursor(i-16, 1);
          lcd.print('0' + pos[i] - 1);
         }
    }
     
     
  14. Delofon

    Delofon Нуб

    ничего не получилось, снова.
     
  15. ostrov

    ostrov Гуру

    Попробуйте обычные символы использовать. Их можно получить из того что есть по формуле 0x30+N где N цифра 0-9.
     
  16. Delofon

    Delofon Нуб

    Хм, забавно. Решил через серийный порт посмотреть, что у меня происходит на 32-ой позиции - там просто случайные числа. Ни 0, ни 1, ни 2, ни 3, ни 4, а какие-то большие числа, поэтому косяк не с функцией draw :eek:
     
  17. b707

    b707 Гуру

    Нашел ошибку, третья строка функции draw у вас должна быть не
    for(char i = 0; i < pos[32-1];i++)

    а
    for(char i = 0; i <32;i++)
     
  18. b707

    b707 Гуру

    с функцией draw тоже косяк - см выше, вы вообще в коде до 32 позиции не добираетесь никогда
     
  19. Delofon

    Delofon Нуб

    спасибо огромное, объекты прорисовались.