Игра Flappy Bird на MAX7219


#define PIN_BUTTON  2
#define PIN_CS     10
#define PIN_CLK    11
#define PIN_DIN    12
#define ADDR 0

#define GAME_STATE_RUNNING 1
#define GAME_STATE_END     2

#define FIELD_WIDTH  8
#define FIELD_HEIGHT 8
#define FIELD_SIZE   FIELD_WIDTH*FIELD_HEIGHT
#define BIRD_SPEED   200  // delay in ms

const byte endScreen[] = {B10000001, B01000010, B00100100, B00011000, B00011000, B00100100, B01000010, B10000001};
const byte obstacleTypes[] = {B11000011, B10001111, B11000111, B11100011, B10011111, B11001111, B11100111, B11110011};

LedControl ledMatrix = LedControl(PIN_DIN, PIN_CLK, PIN_CS, 1);
bool buttonState;
byte birdPos, obstacles[8], gameState, nextObstacle;
unsigned long currentMillis, lastBirdAction, lastLevelAction;
int levelSpeed, gameScore;

void setup()
{
  randomSeed(analogRead(0));
  pinMode(PIN_BUTTON, INPUT);
  ledMatrix.shutdown(ADDR, false);
  ledMatrix.setIntensity(ADDR, 8);
  ledMatrix.clearDisplay(ADDR);
  Serial.begin(9600);
  initGame();
}

void loop()
{
  switch (gameState) {
    case GAME_STATE_RUNNING:
      for (byte row = 0; row < FIELD_WIDTH; row++) {
        if (row == 2) {
          ledMatrix.setRow(ADDR, row, obstacles[row] | birdPos);
        } else {
          ledMatrix.setRow(ADDR, row, obstacles[row]);
        }
      }
      if (birdPos <= 0 || birdPos >= 255) {
        endGame();
        break;
      }
      currentMillis = millis();
      processObstacles();
      if (currentMillis - lastBirdAction > BIRD_SPEED) {
        setBirdPos(true);
      }
      if (isButtonPressed()) {
        setBirdPos(false);
      }
      break;
    case GAME_STATE_END:
      if (isButtonPressed()) {
        initGame();
      }
      break;
  }
}

void initGame()
{
  buttonState = false;
  lastBirdAction = millis();
  lastLevelAction = millis();
  levelSpeed = 500;
  birdPos = B00001000;
  nextObstacle = 1;
  gameState = GAME_STATE_RUNNING;
  gameScore = 0;
  ledMatrix.clearDisplay(ADDR);
  for (byte i = 0; i < 8; i++) {
    obstacles[i] = B00000000;
  }
}

void endGame()
{
  gameState = GAME_STATE_END;
  Serial.println("Game over! You score = " + String(gameScore));
  for (byte row = 0; row < 8; row++) {
    ledMatrix.setRow(ADDR, row, endScreen[row]);
  }
  delay(1000);
}

void setBirdPos(bool leftShift)
{
  if (leftShift) {
    birdPos <<= 1;
  } else {
    birdPos >>= 1;
  }
  for (byte i = 0; i < 8; i++) {
    if (bitRead(birdPos, i) == 1 && bitRead(obstacles[2], i) == 1) {
      endGame();
      return;
    }
  }
  lastBirdAction = currentMillis;
}

void processObstacles()
{
  if (currentMillis - lastLevelAction <= levelSpeed) {
    return;
  }
  for (byte i = 1; i < FIELD_WIDTH; i++) {
    obstacles[i - 1] = obstacles[i];
  }
  if (nextObstacle <= 0) {
    obstacles[FIELD_WIDTH - 1] = obstacleTypes[random(sizeof(obstacleTypes))];
    nextObstacle = 3;
    if (levelSpeed > 50) {
      levelSpeed -= 20;
    }
  } else {
    obstacles[FIELD_WIDTH - 1] = B00000000;
    nextObstacle--;
  }

  if (bitRead(obstacles[2], 0) == 0 && bitRead(obstacles[1], 0) == 1) {
    gameScore++;
  }

  lastLevelAction = currentMillis;
}

bool isButtonPressed()
{
  if (!buttonState) {
    if (digitalRead(PIN_BUTTON) == LOW) {
      buttonState = true;
      return true;
    }
  } else {
    if (digitalRead(PIN_BUTTON) == HIGH) {
      buttonState = false;
    }
  }
  return false;
}

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

Удачи!

доработай, мы разрешаем.

1 лайк

По номеру телефона или карты перевод планируется?

И три цифры с оборота карты обязательно нужно указать!!! :smiley:

Лучше делать на ST7735.

Я правда менял вид игры, для играбельности.

Мне нужно обязательно использовать MAX7219 и данный код…

Ну не знаю, это чужой для вас проект не очень играбельный, препятствия как то криво появляются. Как вы будете выводить к примеру результат 25 на одну матрицу? Странные желания.
8x8 LED-Dot-Matrix II.

Желания не мои, а код вполне рабочий, человека не устроило только то, что нет отображения очков на экране

Очки ННАДА

1 лайк

Скажи преподу, чтоб изменил задание

1 лайк

Да и думаю, что 25 можно вывести, используя двухмерный массив

Не получится

поздно уже, сессия скоро.
Да и куда ему менять что-то, он наверняка и этот голимый код целиком в инете списал

Да, я ссылку дал выше. Только это скорее препод содрал и придумал задания-модернизации, они более тяжкие. Но с экранчиками было бы интересней, да и стоят они чуть дороже этой матрицы на плате.

В Армии, сынок, тебе устроят игры. Графика супер, только сюжет гамно.

Сынок, у меня билет, диванный эксперт

да ладно, когда тебе сразу выдают конечный результат (расчётное время жизни десантника два часа) начинаешь ценить каждую минуту )))

1 лайк

3x7 цифры выводятся.

Или в восьмеричной системе точечками.