Created
March 30, 2022 20:52
-
-
Save 46bit/1e14da52d30afea3f3ef0412df7997f4 to your computer and use it in GitHub Desktop.
Arduino program to render a basic Snake effect on an Adafruit Matrix Portal attached to a 32x64 LED matrix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Adafruit_SleepyDog.h> | |
#include <Adafruit_Protomatter.h> | |
#define HEIGHT 32 | |
#define WIDTH 64 | |
#define LED_COUNT (HEIGHT*WIDTH) | |
uint8_t rgbPins[] = {7, 8, 9, 10, 11, 12}; | |
uint8_t addrPins[] = {17, 18, 19, 20}; | |
uint8_t clockPin = 14; | |
uint8_t latchPin = 15; | |
uint8_t oePin = 16; | |
Adafruit_Protomatter matrix(64, 4, 1, rgbPins, 4, addrPins, clockPin, latchPin, oePin, true); | |
struct segment_t { | |
uint8_t x; | |
uint8_t y; | |
}; | |
segment_t init_segments[LED_COUNT] = { | |
segment_t { 9, 0 }, | |
segment_t { 8, 0 }, | |
segment_t { 7, 0 }, | |
segment_t { 6, 0 }, | |
segment_t { 5, 0 }, | |
segment_t { 4, 0 }, | |
segment_t { 3, 0 }, | |
segment_t { 2, 0 }, | |
segment_t { 1, 0 }, | |
segment_t { 0, 0 }, | |
}; | |
struct snake_t { | |
uint16_t segment_count; | |
segment_t *segments; | |
}; | |
segment_t food = {23, 15}; | |
snake_t snake = { | |
10, | |
init_segments | |
}; | |
void snake_move(snake_t *snake, int16_t dx, int16_t dy) { | |
uint8_t new_head_x = snake->segments[0].x + dx; | |
uint8_t new_head_y = snake->segments[0].y + dy; | |
if (food.x == new_head_x && food.y == new_head_y) { | |
snake->segment_count++; | |
/*snake->segments = realloc(snake->segments, snake->segment_count);*/ | |
} | |
for (int i = snake->segment_count-1; i > 0; i--) { | |
snake->segments[i] = snake->segments[i-1]; | |
} | |
snake->segments[0].x += dx; | |
snake->segments[0].y += dy; | |
} | |
void setup(void) { | |
Serial.begin(115200); | |
ProtomatterStatus status = matrix.begin(); | |
Serial.print("Protomatter begin() status: "); | |
Serial.println((int)status); | |
if(status != PROTOMATTER_OK) { | |
for(;;); | |
} | |
matrix.show(); | |
} | |
void loop(void) { | |
if (food.x == snake.segments[0].x && food.y == snake.segments[0].y) { | |
food.x = (food.x * 9 + snake.segment_count) % WIDTH; | |
food.y = (food.y * 7 + snake.segment_count) % HEIGHT; | |
} | |
matrix.fillScreen(0x0); | |
matrix.drawPixel( | |
snake.segments[snake.segment_count-1].x, | |
snake.segments[snake.segment_count-1].y, | |
matrix.color565(0, 0, 0) | |
); | |
int16_t dx = 0; | |
int16_t dy = 0; | |
dx = food.x - snake.segments[0].x; | |
dx /= abs(dx); | |
dy = food.y - snake.segments[0].y; | |
dy /= abs(dy); | |
if (dx != 0 && dx != 0) { | |
if (abs(dy) > abs(dx)) { | |
dx = 0; | |
} else { | |
dy = 0; | |
} | |
} | |
snake_move(&snake, dx, dy); | |
if (snake.segment_count > LED_COUNT) { | |
reset(); | |
} | |
uint16_t intensity_loss_per_segment = 24500 / (uint16_t) snake.segment_count; | |
for (int16_t i = snake.segment_count-1; i >= 0; i--) { | |
uint8_t intensity = 255 - (uint8_t) ((intensity_loss_per_segment * i) / 100); | |
matrix.drawPixel(snake.segments[i].x, snake.segments[i].y, matrix.color565(0, intensity, 0)); | |
} | |
matrix.drawPixel(food.x, food.y, matrix.color565(255, 255, 255)); | |
//noInterrupts(); | |
matrix.show(); | |
//interrupts(); | |
delay(2); //50); //10); //2); //100); | |
} | |
void reset() { | |
// Make a watchdog timer expire, to trigger a board reset | |
Watchdog.enable(1); | |
while (true) {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment