FLAPPY BIRD

Реализация популярной игры Flappy Bird на платформе ATWatch. Бесконечная игра, в которой необходимо управлять маленькой птичкой и как можно дольше не врезаться в препятствия в виде труб.

Простой вариант кода:
#include 
#include 
#include 
#include "GyverButton.h"

#define OLED_DC    26
#define OLED_CS    31
#define OLED_RESET 24
#define BTN1       2
#define BTN2       12
#define BTN3       13
#define BuzzerPin  15

static const unsigned char PROGMEM PicBird1[] =
{
  0x0, 0x0, 0x0,
  0x3, 0xf0, 0x0,
  0xc, 0x48, 0x0,
  0x10, 0x84, 0x0,
  0x78, 0x8a, 0x0,
  0x84, 0x8a, 0x0,
  0x82, 0x42, 0x0,
  0x82, 0x3f, 0x0,
  0x82, 0x40, 0x80,
  0x44, 0xbf, 0x0,
  0x38, 0x41, 0x0,
  0x10, 0x3e, 0x0,
  0xf, 0xc0, 0x0
};

static const unsigned char PROGMEM PicBird2[] =
{
  0x0, 0x0, 0x0,
  0x3, 0xf0, 0x0,
  0xc, 0x48, 0x0,
  0x10, 0x84, 0x0,
  0x20, 0x8a, 0x0,
  0x40, 0x8a, 0x0,
  0x40, 0x42, 0x0,
  0x7c, 0x3f, 0x0,
  0x82, 0x40, 0x80,
  0x84, 0xbf, 0x0,
  0x88, 0x41, 0x0,
  0x78, 0x3e, 0x0,
  0x7, 0xc0, 0x0
};

Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
GButton butt1(BTN1, LOW_PULL, NORM_OPEN);
GButton butt2(BTN2, LOW_PULL, NORM_OPEN);
GButton butt3(BTN3, LOW_PULL, NORM_OPEN);

// Высота птички
byte pos = 28;
// Множитель падения
byte fallCount = 0;
// Счёт
byte score = 0;
// Последняя пройдённая труба
byte lastTube = 255;
// Переключатель для анимации
bool animState = false;
// Статус игры
bool gameStatus = true;
// Координаты труб
int tubePos[3];
// Высота труб
int ran[3];
// Время смены анимации и увеличения множителя падения
unsigned long flyTime = 0;
// Время движения труб
unsigned long tubeTime = 0;
// Функция обработки действия кнопок
void buttons();
// Функция обработки конца игры
void gameOver();

void setup()
{
  display.begin(SSD1306_SWITCHCAPVCC);
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  randomSeed(micros());
  // Начальные положения труб (через каждые 44 пикселя)
  tubePos[0] = 50;
  tubePos[1] = 94;
  tubePos[2] = 138;
  // Начальные положения высоты труб
  ran[0] = 0;
  ran[1] = 6;
  ran[2] = -3;
}
void buttons()
{
  // Обновляем состояние кнопок
  butt1.tick();
  butt2.tick();
  butt3.tick();

  // Ждём нажатия любой кнопки
  if (butt1.isClick() || butt2.isClick() || butt3.isClick())
  {
    // Издаём звук
    tone(BuzzerPin, 4000, 100);
    // Если игра запущена то делаем прыжок
    if (gameStatus == false)
    {
      //Верхняя граница
      if (pos > 0)
      {
        fallCount = 0;
        pos -= 10;
      }
    }
    else
    {
      // Перезапуск игры
      gameStatus = false;
      fallCount = 0;
      pos = 28;
      ran[0] = 0;
      ran[1] = 6;
      ran[2] = -3;
      tubePos[0] = 50;
      tubePos[1] = 94;
      tubePos[2] = 138;
      score = 0;
      lastTube = 255;
    }
  }
}
void gameOver()
{
  gameStatus = true;
}
void loop()
{
  buttons();

  display.clearDisplay();
  // Игра окончена выводим счёт
  if (gameStatus == true)
  {
    display.setCursor (0, 50);
    display.println ("Score: ");
    display.setCursor (37, 50);
    display.println (score);
    display.setCursor (60, 30);
    display.println ("Game over");
  }

  if (millis() > flyTime)
  {
    flyTime = millis() + 100;
    if (gameStatus == false)
    {
      // Переключаем анимацию
      animState = !animState;
      // Падение птички
      pos += fallCount;
      // Увеличиваем множитель
      fallCount++;
      // Птичка упала
      if (pos >= 50)
      {
        gameOver();
      }
    }
  }

  if (millis() > tubeTime)
  {
    tubeTime = millis() + 20;
    // Если игра запущена
    if (gameStatus == false)
    {
      // Двигаем все трубы
      for (int i = 0 ; i < 3; i++)
      {
        if (tubePos[i] > 0)
          tubePos[i]--;
        else
        {
          // Если труба достигла границы то передвигаем её в начало
          tubePos[i] = 128;
          ran[i] = random(-20, 20);
        }
      }
    }
  }

  // Рисуем трубы, сверху и снизу
  for (int i = 0 ; i < 3; i++)
  {
    display.drawRect(tubePos[i], 0, 5, 16 - ran[i], 1);
    display.drawRect(tubePos[i], 47 - ran[i], 5, 16 + ran[i], 1);
  }

  // Рисуем птичку
  if (animState)
    display.drawBitmap(20, pos, PicBird1, 17, 13, 1);
  else
    display.drawBitmap(20, pos, PicBird2, 17, 13, 1);

  for (int i = 0 ; i < 3 && gameStatus == false; i++)
  {
    // Если труба находится в зоне птички
    if (tubePos[i] <= 37 && tubePos[i] >= 20)
    {
      // Проверка что бы увеличить счёт только ОДИН раз
      if (lastTube != i)
      {
        lastTube = i;
        score++;
      }
      // Если птичка ударилась об границы
      if ((pos < 16 - ran[i]) || pos + 13 > 47 - ran[i])
      {
        gameOver();
      }
    }
  }
  // Отрисовываем кадр
  display.display();
}

Add a Comment

Вы должны зайти как в для комментирования записи