Загрузка данных


#include <LedControl.h>

// --- ПРОТОТИПЫ ФУНКЦИЙ (чтобы Wokwi не ругался) ---
void initGame();
void readJoystick();
void moveSnake();
void spawnFood();
void drawGame();
void endGame();
void handleGameOver();
void updateRGB();
void setRGB(int r, int g, int b);

// --- ПИНЫ MAX7219 ---
#define DIN_PIN 11
#define CS_PIN 10
#define CLK_PIN 13

// --- ПИНЫ ---
#define JOY_X A0
#define JOY_Y A1
#define JOY_BTN 2
#define BUZZER 9
#define RGB_R 3
#define RGB_G 5
#define RGB_B 6

// --- ОБЪЕКТ ---
LedControl matrix = LedControl(DIN_PIN, CLK_PIN, CS_PIN, 1);

// --- ИГРОВЫЕ ПЕРЕМЕННЫЕ ---
const int SIZE = 8;
int snakeX[64], snakeY[64];
int snakeLength = 3;
int dirX = 1, dirY = 0;
int foodX, foodY;
int score = 0;
bool gameOver = false;

// --- ТАЙМЕРЫ ---
unsigned long lastMove = 0;
unsigned long moveInterval = 250;
unsigned long lastJoyCheck = 0;

void setup() {
  Serial.begin(9600);
  matrix.shutdown(0, false);
  matrix.setIntensity(0, 8);
  matrix.clearDisplay(0);

  pinMode(JOY_BTN, INPUT_PULLUP);
  pinMode(BUZZER, OUTPUT);
  pinMode(RGB_R, OUTPUT);
  pinMode(RGB_G, OUTPUT);
  pinMode(RGB_B, OUTPUT);

  randomSeed(analogRead(A2));
  initGame();

  Serial.println(F("=== SNAKE 8x8 ==="));
  Serial.println(F("Use joystick to move. Press button to restart."));
}

void loop() {
  if (gameOver) {
    handleGameOver();
    return;
  }

  if (millis() - lastJoyCheck > 50) {
    lastJoyCheck = millis();
    readJoystick();
  }

  if (millis() - lastMove > moveInterval) {
    lastMove = millis();
    moveSnake();
    drawGame();
  }
}

void initGame() {
  snakeLength = 3;
  snakeX[0] = 4; snakeY[0] = 4;
  snakeX[1] = 3; snakeY[1] = 4;
  snakeX[2] = 2; snakeY[2] = 4;
  dirX = 1;
  dirY = 0;
  score = 0;
  gameOver = false;
  spawnFood();
  setRGB(0, 255, 0);
  Serial.println(F("[GAME] Started"));
}

void readJoystick() {
  int x = analogRead(JOY_X);
  int y = analogRead(JOY_Y);

  if (x < 300 && dirX != 1) {
    dirX = -1;
    dirY = 0;
  }
  else if (x > 700 && dirX != -1) {
    dirX = 1;
    dirY = 0;
  }
  else if (y < 300 && dirY != 1) {
    dirX = 0;
    dirY = -1;
  }
  else if (y > 700 && dirY != -1) {
    dirX = 0;
    dirY = 1;
  }

  if (digitalRead(JOY_BTN) == LOW) {
    delay(50);
    if (digitalRead(JOY_BTN) == LOW) {
      initGame();
      matrix.clearDisplay(0);
    }
  }
}

void moveSnake() {
  for (int i = snakeLength - 1; i > 0; i--) {
    snakeX[i] = snakeX[i - 1];
    snakeY[i] = snakeY[i - 1];
  }

  snakeX[0] += dirX;
  snakeY[0] += dirY;

  if (snakeX[0] < 0 || snakeX[0] >= SIZE || snakeY[0] < 0 || snakeY[0] >= SIZE) {
    endGame();
    return;
  }

  for (int i = 1; i < snakeLength; i++) {
    if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
      endGame();
      return;
    }
  }

  if (snakeX[0] == foodX && snakeY[0] == foodY) {
    score++;
    snakeLength++;
    tone(BUZZER, 1500, 100);
    Serial.print(F("[SCORE] "));
    Serial.println(score);
    spawnFood();
    updateRGB();
  }
}

void spawnFood() {
  bool valid = false;
  while (!valid) {
    foodX = random(0, SIZE);
    foodY = random(0, SIZE);
    valid = true;
    for (int i = 0; i < snakeLength; i++) {
      if (snakeX[i] == foodX && snakeY[i] == foodY) {
        valid = false;
        break;
      }
    }
  }
}

void drawGame() {
  matrix.clearDisplay(0);
  for (int i = 0; i < snakeLength; i++) {
    matrix.setLed(0, snakeY[i], snakeX[i], true);
  }
  if (millis() % 500 < 250) {
    matrix.setLed(0, foodY, foodX, true);
  }
}

void endGame() {
  gameOver = true;
  tone(BUZZER, 500, 500);
  setRGB(255, 0, 0);
  Serial.print(F("[GAME OVER] Score: "));
  Serial.println(score);
}

void handleGameOver() {
  static unsigned long lastBlink = 0;
  static bool state = false;
  if (millis() - lastBlink > 300) {
    lastBlink = millis();
    state = !state;
    for (int r = 0; r < 8; r++) {
      for (int c = 0; c < 8; c++) {
        matrix.setLed(0, r, c, state);
      }
    }
  }

  if (digitalRead(JOY_BTN) == LOW) {
    delay(50);
    if (digitalRead(JOY_BTN) == LOW) {
      matrix.clearDisplay(0);
      initGame();
    }
  }
}

void updateRGB() {
  if (score < 5) {
    setRGB(0, 255, 0);
  } else if (score < 10) {
    setRGB(255, 255, 0);
  } else if (score < 15) {
    setRGB(255, 128, 0);
  } else {
    setRGB(255, 0, 0);
  }
}

void setRGB(int r, int g, int b) {
  analogWrite(RGB_R, r);
  analogWrite(RGB_G, g);
  analogWrite(RGB_B, b);
}