Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Arduino-клон Flappy Bird на TFT-сенсорном экране: пошаговый гайд

Сделаем копию популярной игры Flappy Bird на Arduino с TFT-сенсорным экраном. Управление птицей касанием, избегаем движущихся столбов, скорость растёт. Рекорд сохраняется в EEPROM даже без питания.

Обзор

Игра простая, но затягивающая. В предыдущем туториале (Arduino TFT Tutorial) мы изучили работу с TFT-экраном, а здесь разберём код игры.

Arduino-клон Flappy Bird на TFT-сенсорном экране: пошаговый гайд

Исходный код

Код разбит на секции с пояснениями. В конце — полный листинг.

Используем библиотеки UTFT и URTouch (Henning Karlsen, RinkyDinkElectronics.com) и EEPROM для хранения рекорда.

Создаём объекты дисплея и тача, задаём шрифты и битмап птицы. Переменные: координаты столбов (xP, yP), птицы (yB), скорость падения, счёт, рекорд.

#include <UTFT.h>
#include <URTouch.h>
#include <EEPROM.h>
// Объекты
UTFT myGLCD(SSD1289,38,39,40,41); // Параметры под ваш дисплей
URTouch myTouch(6, 5, 4, 3, 2);
// Шрифты
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];
extern unsigned int bird01[0x41A]; // Битмап птицы
int x, y; // Координаты касания
// Игра
int xP = 319, yP = 100, yB = 50;
int movingRate = 3, fallRateInt = 0; float fallRate = 0;
int score = 0, lastSpeedUpScore = 0, highestScore;
boolean screenPressed = false, gameStarted = false;

void setup() {
  myGLCD.InitLCD(); myGLCD.clrScr();
  myTouch.InitTouch(); myTouch.setPrecision(PREC_MEDIUM);
  highestScore = EEPROM.read(0);
  initiateGame();
}

Функция initiateGame() рисует стартовый экран: голубой фон, земля, текст «Score», «Highest Score», «TAP TO START», птицу. Ждёт касания экрана. Касание в правом верхнем углу сбрасывает рекорд. Касание в любой другой точке — старт игры.

Arduino-клон Flappy Bird на TFT-сенсорном экране: пошаговый гайд
void initiateGame() {
  myGLCD.clrScr();
  myGLCD.setColor(114,198,206); myGLCD.fillRect(0,0,319,239); // фон
  myGLCD.setColor(221,216,148); myGLCD.fillRect(0,215,319,239); // земля
  myGLCD.setColor(47,175,68); myGLCD.fillRect(0,205,319,214); // трава
  // Текст
  myGLCD.setColor(0,0,0); myGLCD.setBackColor(221,216,148); myGLCD.setFont(BigFont);
  myGLCD.print("Score:",5,220);
  myGLCD.setFont(SmallFont); myGLCD.print("HowToMechatronics.com",140,220);
  myGLCD.setColor(0,0,0); myGLCD.setBackColor(114,198,206);
  myGLCD.print("Highest Score: ",5,5); myGLCD.printNumI(highestScore,120,6);
  myGLCD.print(">RESET<",255,5); myGLCD.drawLine(0,23,319,23);
  myGLCD.print("TAP TO START",CENTER,100);
  drawBird(yB);
  while(!gameStarted) {
    if(myTouch.dataAvailable()) {
      myTouch.read(); x=myTouch.getX(); y=myTouch.getY();
      if(x>=250 && x<=319 && y>=0 && y<=28) { // RESET
        highestScore=0;
        myGLCD.setColor(114,198,206); myGLCD.fillRect(120,0,150,22);
        myGLCD.setColor(0,0,0); myGLCD.printNumI(highestScore,120,5);
      }
      if(x>=0 && x<=319 && y>=30 && y<=239) {
        gameStarted=true;
        myGLCD.setColor(114,198,206); myGLCD.fillRect(0,0,319,32);
      }
    }
  }
  myGLCD.setColor(114,198,206); myGLCD.fillRect(85,100,235,116); // стираем TAP TO START
}

В loop() столбы движутся влево (xP уменьшается на movingRate). Птица падает с ускорением (fallRate растёт). Проверяются столкновения с верхом/низами экрана и столбами. Птица рисуется функцией drawBird(). Когда столб уходит за экран (xP < -51), xP сбрасывается, yP — новая случайная высота, счёт увеличивается.

Arduino-клон Flappy Bird на TFT-сенсорном экране: пошаговый гайд

Проблема: низкая частота обновления TFT вызывает мерцание при полной перерисовке. Решение: перерисовывать только движущиеся объекты. Функция drawPilars() рисует столбы в новой позиции и закрашивает синим следы старой.

void drawPilars(int x, int y) {
  if(x>=270) {
    myGLCD.setColor(0,200,20); myGLCD.fillRect(318,0,x,y-1);
    myGLCD.setColor(0,0,0); myGLCD.drawRect(319,0,x-1,y);
    myGLCD.setColor(0,200,20); myGLCD.fillRect(318,y+81,x,203);
    myGLCD.setColor(0,0,0); myGLCD.drawRect(319,y+80,x-1,204);
  } else if(x<=268) {
    myGLCD.setColor(114,198,206); myGLCD.fillRect(x+51,0,x+60,y); // право
    myGLCD.setColor(0,200,20); myGLCD.fillRect(x+49,1,x+1,y-1); // столб
    myGLCD.setColor(0,0,0); myGLCD.drawRect(x+50,0,x,y); // рамка
    myGLCD.setColor(114,198,206); myGLCD.fillRect(x-1,0,x-3,y); // лево
    // нижний столб
    myGLCD.setColor(114,198,206); myGLCD.fillRect(x+51,y+80,x+60,204);
    myGLCD.setColor(0,200,20); myGLCD.fillRect(x+49,y+81,x+1,203);
    myGLCD.setColor(0,0,0); myGLCD.drawRect(x+50,y+80,x,204);
    myGLCD.setColor(114,198,206); myGLCD.fillRect(x-1,y+80,x-3,204);
  }
  myGLCD.setColor(0,0,0); myGLCD.setBackColor(221,216,148); myGLCD.setFont(BigFont);
  myGLCD.printNumI(score,100,220);
}
Arduino-клон Flappy Bird на TFT-сенсорном экране: пошаговый гайд

Птица — битмап, конвертированный из фото через ImageConverter565. Функция drawBird() рисует битмап и закрашивает синим области выше и ниже птицы, стирая её предыдущее положение.

void drawBird(int y) {
  myGLCD.drawBitmap(50, y, 35, 30, bird01);
  myGLCD.setColor(114,198,206);
  myGLCD.fillRoundRect(50,y,85,y-6);
  myGLCD.fillRoundRect(50,y+30,85,y+36);
}

Управление: касание экрана задаёт fallRate = -6 (прыжок). Удержание экрана игнорируется (нужно тапнуть). Каждые 5 очков movingRate увеличивается — игра ускоряется.

Функция gameOver(): пауза 1 сек, экран «GAME OVER», счёт, обратный отсчёт 3–2–1, запись рекорда в EEPROM, сброс переменных, рестарт через initiateGame().

Arduino-клон Flappy Bird на TFT-сенсорном экране: пошаговый гайд
void gameOver() {
  delay(1000);
  myGLCD.clrScr(); myGLCD.setColor(255,255,255); myGLCD.setBackColor(0,0,0); myGLCD.setFont(BigFont);
  myGLCD.print("GAME OVER",CENTER,40); myGLCD.print("Score:",100,80); myGLCD.printNumI(score,200,80);
  myGLCD.print("Restarting...",CENTER,120); myGLCD.setFont(SevenSegNumFont);
  myGLCD.printNumI(2,CENTER,150); delay(1000); myGLCD.printNumI(1,CENTER,150); delay(1000);
  if(score > highestScore) { highestScore=score; EEPROM.write(0,highestScore); }
  xP=319; yB=50; fallRate=0; score=0; lastSpeedUpScore=0; movingRate=3; gameStarted=false;
  initiateGame();
}

Полный код игры

/* Arduino Game Project
 * by Dejan Nedelkovski, www.HowToMechatronics.com
 * Uses UTFT & URTouch by Henning Karlsen (www.RinkyDinkElectronics.com)
 */
#include <UTFT.h> #include <URTouch.h> #include <EEPROM.h>
UTFT myGLCD(SSD1289,38,39,40,41); URTouch myTouch(6,5,4,3,2);
extern uint8_t SmallFont[]; extern uint8_t BigFont[]; extern uint8_t SevenSegNumFont[];
extern unsigned int bird01[0x41A];
int x,y; int xP=319,yP=100,yB=50,movingRate=3,fallRateInt=0; float fallRate=0;
int score=0,lastSpeedUpScore=0,highestScore; boolean screenPressed=false,gameStarted=false;
void setup(){ myGLCD.InitLCD(); myGLCD.clrScr(); myTouch.InitTouch(); myTouch.setPrecision(PREC_MEDIUM); highestScore=EEPROM.read(0); initiateGame(); }
void loop(){ xP-=movingRate; drawPilars(xP,yP); yB+=fallRateInt; fallRate+=0.4; fallRateInt=int(fallRate);
  if(yB>=180||yB<=0){gameOver();}
  if(xP<=85&&xP>=5&&yB<=yP-2){gameOver();}
  if(xP<=85&&xP>=5&&yB>=yP+60){gameOver();}
  drawBird(yB);
  if(xP<=-51){xP=319; yP=rand()%100+20; score++;}
  if(myTouch.dataAvailable()&&!screenPressed){fallRate=-6; screenPressed=true;}
  else if(!myTouch.dataAvailable()&&screenPressed){screenPressed=false;}
  if((score-lastSpeedUpScore)==5){lastSpeedUpScore=score; movingRate++;}
}
// initiateGame, drawPilars, drawBird, gameOver — как выше

Ссылка на скачивание скетча, изображения птицы и битмап-файла.

Производственный процесс

  1. Создание потрясающей системы Ambilight для монитора на Arduino
  2. Создание классической игры Pong на Arduino UNO с OLED-дисплеем: пошаговый урок
  3. DIY USB-геймпад на Arduino: собственный высокопроизводительный контроллер
  4. Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками
  5. Гигантский анимированный LEGO-человечек: игра «Операция» на Arduino
  6. Детектор аудиочастот на Arduino: измеряем пик громкости с высокочувствительным модулем
  7. Крестики-нолики на Arduino с матрицей MAX7219 и картонным корпусом
  8. Сборка надежного таймера обратного отсчета на Arduino с 7-сегментным дисплеем SparkFun
  9. Pixel Chaser: игра на один тап с NeoPixel Ring и Arduino Nano
  10. Самодельный RC Porsche на Arduino: Пошаговое руководство