#include <SPI.h>
// The chip select pin
// Aqui ele dá #include da biblioteca
//Aqui os defines que substitui no código por esses valores
#define CS 10
#define DECODE_MODE 9
#define INTENSITY 0x0A
#define SCAN_LIMIT 0x0B
#define SHUTDOWN 0x0C
#define DISPLAY_TEST 0x0F
#define left_button 2
#define right_button 3
//Aqui várias definições de variáveis
byte move_left = 0;
byte move_right = 0;
// Snake
int snake_l = 2;
const int max_len = 30;
int snake[max_len][2];
byte cur_heading = 0;
// Food
int blob[2] = { 0, 0 };
int is_eaten = 1;
// Scene
byte scene[8] = { 0 };
byte last_left = HIGH;
byte last_right = HIGH;
// A general function to send data to the MAX7219
void SendData(uint8_t address, uint8_t value) {
digitalWrite(CS, LOW);
SPI.transfer(address);
SPI.transfer(value);
digitalWrite(CS, HIGH);
}
// Function to initialize the game variables
void init_game() {
is_eaten = 1;
move_left = 0;
move_right = 0;
cur_heading = 0;
snake_l = 2;
for (int i = 0; i < max_len; i++)
for (int j = 0; j < 2; j++)
snake[i][j] = 0;
snake[max_len - 1][0] = 2;
snake[max_len - 1][1] = 5;
snake[max_len - 2][0] = 1;
snake[max_len - 2][1] = 5;
refresh_scene();
}
// Function to draw snake on gamescene
void spawn_snake() {
for (int j = max_len - snake_l; j < max_len; j++) {
if (snake[j][0] <= 0) snake[j][0] += 8;
if (snake[j][0] > 8) snake[j][0] -= 8;
if (snake[j][1] <= 0) snake[j][1] += 8;
if (snake[j][1] > 8) snake[j][1] -= 8;
scene[snake[j][0] - 1] |= (1 << (snake[j][1] - 1));
}
}
// Function to update the position and length of the snake
void snake_move() {
if (snake[max_len - 1][0] == blob[0] && snake[max_len - 1][1] == blob[1]) {
is_eaten = 1;
snake_l++;
}
for (int i = snake_l - 1; i >= 1; i--) {
snake[max_len - 1 - i][0] = snake[max_len - i][0];
snake[max_len - 1 - i][1] = snake[max_len - i][1];
}
if (move_left) {
cur_heading = (cur_heading + 1) % 4;
move_left = 0;
}
else if (move_right) {
cur_heading = (cur_heading + 3) % 4;
move_right = 0;
}
if (cur_heading == 0) snake[max_len - 1][0]++;
if (cur_heading == 1) snake[max_len - 1][1]--;
if (cur_heading == 2) snake[max_len - 1][0]--;
if (cur_heading == 3) snake[max_len - 1][1]++;
}
// Function to generate a blob and draw the blob on the gamescene
void blob_generator() {
if (is_eaten) {
blob[0] = random(1, 9);
blob[1] = random(1, 9);
is_eaten = 0;
}
scene[blob[0] - 1] |= (1 << (blob[1] - 1));
}
// Function to redraw the gamescene to the LED matrix with updated variables
void refresh_scene() {
for (int i = 0; i < 8; i++) scene[i] = 0;
snake_move();
spawn_snake();
blob_generator();
for (int i = 1; i < 9; i++)
SendData(i, scene[i - 1]);
}
// Setup function
void setup() {
// GPIO Configuration
pinMode(left_button, INPUT_PULLUP);
pinMode(right_button, INPUT_PULLUP);
pinMode(CS, OUTPUT);
//Serial inicialization (Only for debug)
Serial.begin(9600);
// SPI configuration
SPI.begin();
SendData(DISPLAY_TEST, 0x00);
SendData(DECODE_MODE, 0x00);
SendData(INTENSITY, 0x0F);
SendData(SCAN_LIMIT, 0x0f);
SendData(SHUTDOWN, 0x01);
// Random seed generation...
//Uses the noise in the analog channel 0 to create a random seed
randomSeed(analogRead(0));
// Start the game
init_game();
}
//Loop for processing and rendering
void loop() {
byte now_left = digitalRead(left_button);
byte now_right = digitalRead(right_button);
if (last_left == HIGH && now_left == LOW) {
move_left = 1;
}
if (last_right == HIGH && now_right == LOW) {
move_right = 1;
}
last_left = now_left;
last_right = now_right;
// colisão com corpo
for (int i = 0; i < max_len - 1; i++) {
if (snake[i][0] == snake[max_len - 1][0] &&
snake[i][1] == snake[max_len - 1][1]) {
for (int j = 0; j < 4; j++) {
SendData(DISPLAY_TEST, 1);
delay(300);
SendData(DISPLAY_TEST, 0);
delay(300);
}
init_game();
}
}
// Keep refreshing the matrix with updated data....
refresh_scene();
delay(250);
Serial.print("Left Button: ");
Serial.println(digitalRead(left_button));
Serial.print("Right Button: ");
Serial.println((digitalRead(right_button)));
}