#include "LedControl.h"
struct Pin {//Секция настройки штифта
static const short joystickX = A2;
static const short joystickY = A3;
static const short joystickVCC = 15;
static const short joystickGND = 14;
static const short CLK = 3;
static const short CS = 4;
static const short DIN = 5;
};
const short initialSnakeLength = 3;//Длина начальной змейки
void setup() {
Serial.begin(9600); // Установите скорость передачи данных в бодах
initialize(); // инициализировать
showSnakeMessage(); // //Прокрутите страницу, чтобы отобразить символыSNAKE
}
void loop() {
generateFood(); // Если вы не используете продукты питания, создайте их сами
scanJoystick(); // Определите направление коромысла
calculateSnake(); // Отрегулируйте положение змеи, чтобы определить, съела ли она пищу и потерпела ли неудачу
GameStates(); //Определите состояние игры, окончена ли она, и анимация будет воспроизведена в конце
}
LedControl matrix(Pin::DIN, Pin::CLK, Pin::CS, 1);
struct Point {
int row = 0, col = 0;
Point(int row = 0, int col = 0): row(row), col(col) {}
};
struct Coordinate {
int x = 0, y = 0;
Coordinate(int x = 0, int y = 0): x(x), y(y) {}
};
bool win = false;
bool gameOver = false;
Point snake;//Создайте массив для тела змеи
Point food(-1, -1);//Создайте массив местоположений продуктов питания, начальное местоположение продуктов питания до того, как они не будут созданы, то есть продукты питания не будут отображаться
Coordinate joystickHome(500, 500);//Установите исходное положение джойстика по умолчанию
int snakeLength = initialSnakeLength; //Установите длину змейки на исходную заданную длину
int snakeDirection = 0; // Змея не двигается до использования джойстика
const short up = 1;
const short right = 2;
const short down = 3;
const short left = 4;
const int joystickThreshold = 160;//Установлено пороговое значение коромысла, чем меньше коромысло, тем чувствительнее коромысло, подходящим значением является 160
int gameboard[8][8] = {};//Создайте массив змеиных тел
//Готовьте еду и судите, чтобы победить
void generateFood() {
if (food.row == -1 || food.col == -1) {
if (snakeLength >= 64) {
win = true;//Если длина змейки достигает 64, она считается выигравшей
return;
}
do {
food.col = random(8);
food.row = random(8);
} while (gameboard[food.row][food.col] > 0);//Измените расположение блюд на случайное
}
matrix.setLed(0, food.row, food.col,1);//Покажите местоположение следующего блюда
}
void scanJoystick() {
int previousDirection = snakeDirection;//Выполните резервное копирование направления текущей змеи
delay(100);
analogRead(Pin::joystickY) < joystickHome.y - joystickThreshold ? snakeDirection = up : 0;
analogRead(Pin::joystickY) > joystickHome.y + joystickThreshold ? snakeDirection = down : 0;
analogRead(Pin::joystickX) < joystickHome.x - joystickThreshold ? snakeDirection = left : 0;
analogRead(Pin::joystickX) > joystickHome.x + joystickThreshold ? snakeDirection = right : 0;
// Игнорируйте изменение направления на 180 градусов и не оглядывайтесь на месте
snakeDirection + 2 == previousDirection && previousDirection != 0 ? snakeDirection = previousDirection : 0;
snakeDirection - 2 == previousDirection && previousDirection != 0 ? snakeDirection = previousDirection : 0;
}
// Отрегулируйте положение змеи, чтобы определить, съела ли она пищу
void calculateSnake() {
switch (snakeDirection) {
case up:
snake.row--;//Змея движется вверх
fixEdge();//Если змея выйдет за край, это приведет к тому, что она появится на другой стороне экрана
matrix.setLed(0, snake.row, snake.col, 1);
break;
case right:
snake.col++;//Змея движется вправо
fixEdge();
matrix.setLed(0, snake.row, snake.col, 1);
break;
case down:
snake.row++;//Змея движется вниз
fixEdge();
matrix.setLed(0, snake.row, snake.col, 1);
break;
case left:
snake.col--;//Змея движется влево
fixEdge();
matrix.setLed(0, snake.row, snake.col, 1);
break;
default://Уйду, если ты не будешь двигаться
return;
}
//Определите, произошел ли сбой
if (gameboard[snake.row][snake.col] > 1 && snakeDirection != 0) {
//Определите, совпадает ли положение головы змеи с туловищем, избегая при этом ситуации, сложившейся в начале
gameOver = true;
return;
}
//Определите, съели ли вы пищу
if (snake.row == food.row && snake.col == food.col) {//Если координаты головы змеи и еды совпадают
food.row = -1; //Сброс питания
food.col = -1;
snakeLength++;//Длина змеи увеличилась
//Увеличьте размеры всех змеиных тел
for (int row = 0; row < 8; row++) {//Горизонтальное увеличение
for (int col = 0; col < 8; col++) {//Вертикальное увеличение
if (gameboard[row][col] > 0 ) {
gameboard[row][col]++;
}
}
}
}
gameboard[snake.row][snake.col] = snakeLength + 1;
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
if (gameboard[row][col] > 0 ) {
gameboard[row][col]--;
}
matrix.setLed(0, row, col, gameboard[row][col] == 0 ? 0 : 1);//Покажите тело змеи
}
}
}
// Если змея выйдет за край, это приведет к тому, что она появится на другой стороне экрана
void fixEdge() {
snake.col < 0 ? snake.col += 8 : 0;
snake.col > 7 ? snake.col -= 8 : 0;
snake.row < 0 ? snake.row += 8 : 0;
snake.row > 7 ? snake.row -= 8 : 0;
}
void GameStates() {
if (gameOver || win) {
unrollSnake();//Сбросить змей и еду
if (gameOver) showGameOverMessage();//Если вы проиграете, перейдите к игре GG!
else if (win) ;
//Сброс игрового контента
win = false;
gameOver = false;
snake.row = random(8);//Установите змейку в случайном месте
snake.col = random(8);
food.row = -1;
food.col = -1;
snakeLength = initialSnakeLength;//Установите длину змейки на исходную заданную длину
snakeDirection = 0;//Змея не двигается до использования джойстика
memset(gameboard, 0, sizeof(gameboard[0][0]) * 8 * 8);//Очистите массив от тела змеи
matrix.clearDisplay(0);//задерживать
}
}
void unrollSnake() {
matrix.setLed(0, food.row, food.col, 0);//Заставьте еду исчезнуть
delay(800);
for (int i = 1; i <= snakeLength; i++) {
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
if (gameboard[row][col] == i) {
matrix.setLed(0, row, col, 0);
delay(100); //Заставьте тело змеи исчезнуть по порядку
}
}
}
}
}
void initialize() {
pinMode(Pin::joystickVCC, OUTPUT);//Установите joystickVCC в режим вывода
digitalWrite(Pin::joystickVCC, HIGH);//Установите joystickVCC на высокое значение
pinMode(Pin::joystickGND, OUTPUT);//Установите joystickGND в режим вывода
digitalWrite(Pin::joystickGND, LOW);//Установите значение joystickGND на высокое
matrix.shutdown(0, false);//При значении status-true включите режим энергосбережения соответствующей точечной матрицы и установите для него значение false, когда его необходимо использовать в обычном режиме.
matrix.setIntensity(0, 6);//Установите значение яркости (0-15 от темного до яркого).
matrix.clearDisplay(0);//Точечный матричный экран / цифровой трубчатый прозрачный экран
snake.row = random(8);
snake.col = random(8);//Установите произвольное начальное положение змейки
}
//Часть модели шрифта
const PROGMEM bool snakeMessage[8][56] = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
const PROGMEM bool gameOverMessage[8][90] = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
//Прокрутите страницу, чтобы отобразить символы SNAKE
void showSnakeMessage() {
[&] {
for (int d = 0; d < sizeof(snakeMessage[0]) - 7; d++) {
for (int col = 0; col < 8; col++) {
delay(5);
for (int row = 0; row < 8; row++) {
matrix.setLed(0, row, col, pgm_read_byte(&(snakeMessage[row][col + d])));
}
}
}
}();
matrix.clearDisplay(0);
}
//Дисплей с прокруткой GG!
void showGameOverMessage() {
[&] {
for (int d = 0; d < sizeof(gameOverMessage[0]) - 7; d++) {
for (int col = 0; col < 8; col++) {
delay(5);
for (int row = 0; row < 8; row++) {
matrix.setLed(0, row, col, pgm_read_byte(&(gameOverMessage[row][col + d])));
}
}
}
}();
matrix.clearDisplay(0);
}