Das Spiel Snake auf einer 8x8 LED Matrix (dual color - red-green)

Bilder

  

 

   

  

 

   

 

Sourcecode

 // ************************************************** // 3 x 74HC595 & ULN2803 mit 8x8 Matrix red/green // **************************************************

include <TimerOne.h>
include <MsTimer2.h>
include <Bounce.h>
define COLS 8
define ROWS 8
define MATRIX COLS * ROWS
byte col = 0; byte row = 0; long rowoutput; long redoutput; long greenoutput; long redoutputrow; long greenoutputrow; int matrix[MATRIX]; int snake[MATRIX]; int newsnake[MATRIX]; int snakehead = 0; int oldsnakehead = 0; int snaketail = 0; int startingpoint = 15; int direction = 1; boolean buttonPressed = false;

int applecaught = 0; int apple = -1; int applecount = 0;

int empty = 0; int red = 1; int green = 2; int orange = 3;

int button1 = 7; // Left int button2 = 5; // Up int button3 = 6; // Down int button4 = 8; // Right

//Pin connected to ST_CP of 74HC595 int latchPin = 10; //Pin connected to SH_CP of 74HC595 int clockPin = 12; //Pin connected to DS of 74HC595 int dataPin = 11; // RESET Pin int outputEnablePin = 9;

int moveSpeed = 200; unsigned long lastMillis = 0;

// Scroll text String msg = " "; int msgIndex = 0; int alphabetIndex = 0; int i = 0; bool scrollNow = false; bool scrollOnce = false;

const byte alphabets[][6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer

                             0x7E, 0x89, 0x91, 0xA1, 0x7E, 0x00, //  0
                             0x00, 0x41, 0xFF, 0x01, 0x00, 0x00, //  1
                             0x43, 0x85, 0x89, 0x91, 0x61, 0x00, //  2
                             0x42, 0x81, 0x91, 0x91, 0x6E, 0x00, //  3
                             0x18, 0x28, 0x48, 0xFF, 0x08, 0x00, //  4
                             0xF2, 0x91, 0x91, 0x91, 0x8E, 0x00, //  5
                             0x1E, 0x29, 0x49, 0x89, 0x86, 0x00, //  6
                             0x80, 0x8F, 0x90, 0xA0, 0xC0, 0x00, //  7
                             0x6E, 0x91, 0x91, 0x91, 0x6E, 0x00, //  8
                             0x70, 0x89, 0x89, 0x8A, 0x7C, 0x00,  //  9
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x7F, 0x88, 0x88, 0x88, 0x7F, 0x00, //  A
                             0xFF, 0x91, 0x91, 0x91, 0x6E, 0x00, //  B
                             0x7E, 0x81, 0x81, 0x81, 0x42, 0x00, //  C
                             0xFF, 0x81, 0x81, 0x42, 0x3C, 0x00, //  D
                             0xFF, 0x91, 0x91, 0x91, 0x81, 0x00, //  E
                             0xFF, 0x90, 0x90, 0x90, 0x80, 0x00, //  F
                             0x7E, 0x81, 0x89, 0x89, 0x4E, 0x00, //  G
                             0xFF, 0x10, 0x10, 0x10, 0xFF, 0x00, //  H
                             0x81, 0x81, 0xFF, 0x81, 0x81, 0x00, //  I
                             0x06, 0x01, 0x01, 0x01, 0xFE, 0x00, //  J
                             0xFF, 0x18, 0x24, 0x42, 0x81, 0x00, //  K
                             0xFF, 0x01, 0x01, 0x01, 0x01, 0x00, //  L
                             0xFF, 0x40, 0x30, 0x40, 0xFF, 0x00, //  M
                             0xFF, 0x40, 0x30, 0x08, 0xFF, 0x00, //  N
                             0x7E, 0x81, 0x81, 0x81, 0x7E, 0x00, //  O
                             0xFF, 0x88, 0x88, 0x88, 0x70, 0x00, //  P
                             0x7E, 0x81, 0x85, 0x82, 0x7D, 0x00, //  Q
                             0xFF, 0x88, 0x8C, 0x8A, 0x71, 0x00, //  R
                             0x61, 0x91, 0x91, 0x91, 0x8E, 0x00, //  S
                             0x80, 0x80, 0xFF, 0x80, 0x80, 0x00, //  T
                             0xFE, 0x01, 0x01, 0x01, 0xFE, 0x00, //  U
                             0xF0, 0x0C, 0x03, 0x0C, 0xF0, 0x00, //  V
                             0xFF, 0x02, 0x0C, 0x02, 0xFF, 0x00, //  W
                             0xC3, 0x24, 0x18, 0x24, 0xC3, 0x00, //  X
                             0xE0, 0x10, 0x0F, 0x10, 0xE0, 0x00, //  Y
                             0x83, 0x85, 0x99, 0xA1, 0xC1, 0x00, //  Z
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // leer
                             0x06, 0x29, 0x29, 0x29, 0x1F, 0x00, //  a
                             0xFF, 0x09, 0x11, 0x11, 0x0E, 0x00, //  b
                             0x1E, 0x21, 0x21, 0x21, 0x12, 0x00, //  c
                             0x0E, 0x11, 0x11, 0x09, 0xFF, 0x00, //  d
                             0x0E, 0x15, 0x15, 0x15, 0x0C, 0x00, //  e
                             0x08, 0x7F, 0x88, 0x80, 0x40, 0x00, //  f
                             0x30, 0x49, 0x49, 0x49, 0x7E, 0x00, //  g
                             0xFF, 0x08, 0x10, 0x10, 0x0F, 0x00, //  h
                             0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, //  i
                             0x02, 0x01, 0x21, 0xBE, 0x00, 0x00, //  j
                             0xFF, 0x04, 0x0A, 0x11, 0x00, 0x00, //  k
                             0x00, 0x81, 0xFF, 0x01, 0x00, 0x00, //  l
                             0x3F, 0x20, 0x18, 0x20, 0x1F, 0x00, //  m
                             0x3F, 0x10, 0x20, 0x20, 0x1F, 0x00, //  n
                             0x0E, 0x11, 0x11, 0x11, 0x0E, 0x00, //  o
                             0x3F, 0x24, 0x24, 0x24, 0x18, 0x00, //  p
                             0x10, 0x28, 0x28, 0x18, 0x3F, 0x00, //  q
                             0x1F, 0x08, 0x10, 0x10, 0x08, 0x00, //  r
                             0x09, 0x15, 0x15, 0x15, 0x02, 0x00, //  s
                             0x20, 0xFE, 0x21, 0x01, 0x02, 0x00, //  t
                             0x1E, 0x01, 0x01, 0x02, 0x1F, 0x00, //  u
                             0x1C, 0x02, 0x01, 0x02, 0x1C, 0x00, //  v
                             0x1E, 0x01, 0x0E, 0x01, 0x1E, 0x00, //  w
                             0x11, 0x0A, 0x04, 0x0A, 0x11, 0x00, //  x
                             0x00, 0x39, 0x05, 0x05, 0x3E, 0x00, //  y
                             0x11, 0x13, 0x15, 0x19, 0x11, 0x00, //  z
                             0x44, 0x02, 0x12, 0x02, 0x44, 0x00  //  { -> smile
                           };
  
const byte numbers[][3] = { 0x3E, 0x22, 0x3E, // 0

                           0x12, 0x3E, 0x02, // 1
                           0x2E, 0x2A, 0x3A, // 2
                           0x2A, 0x2A, 0x3E, // 3
                           0x38, 0x08, 0x3E, // 4
                           0x3A, 0x2A, 0x2E, // 5
                           0x3E, 0x2A, 0x2E, // 6
                           0x20, 0x20, 0x3E, // 7
                           0x3E, 0x2A, 0x3E, // 8
                           0x3A, 0x2A, 0x3E, // 9
                         };
Bounce bouncer1 = Bounce(button1, 10); Bounce bouncer2 = Bounce(button2, 10); Bounce bouncer3 = Bounce(button3, 10); Bounce bouncer4 = Bounce(button4, 10); int button1value = LOW; int button2value = LOW; int button3value = LOW; int button4value = LOW;

// initialization void setup() {

 //set pins to output because they are addressed in the main loop
 pinMode(latchPin, OUTPUT);
 pinMode(clockPin, OUTPUT);
 pinMode(dataPin, OUTPUT);
 digitalWrite(latchPin, LOW);
 pinMode(outputEnablePin, OUTPUT);
 digitalWrite(outputEnablePin, LOW);
 randomSeed(analogRead(5));
 // buttons to input
 pinMode(button1, INPUT);
 pinMode(button2, INPUT);
 pinMode(button3, INPUT);
 pinMode(button4, INPUT);
 // Enable internal pullup resistors
 digitalWrite(button1, HIGH);
 digitalWrite(button2, HIGH);
 digitalWrite(button3, HIGH);
 digitalWrite(button4, HIGH);
 
 // Timer1 controls output on displays
 Timer1.initialize(2000);
 Timer1.attachInterrupt(outputDisplay);
 
 // Timer2 scrolls text
 MsTimer2::set(120, scroll);
 MsTimer2::start();
 
 buttonPressed = false;
}

// called by timer1 void outputDisplay() {

 if (col >= COLS)
   col = 0;
 greenoutputrow = 0;
 redoutputrow = 0;
 for (int i=0; i<ROWS; i++)
 {
   int value = matrix[col*ROWS+i];
   switch(value) {
case 1: redoutput = 1 << i; greenoutput = 0; break; case 2: redoutput = 0; greenoutput = 1 << i; break; case 3: redoutput = 1 << i; greenoutput = 1 << i; break; default: redoutput = 0; greenoutput = 0; break;

   }
   redoutputrow += redoutput;
   greenoutputrow += greenoutput;
 }
 rowoutput = (1 << col);
 digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, rowoutput);
 shiftOut(dataPin, clockPin, MSBFIRST, greenoutputrow);
 shiftOut(dataPin, clockPin, MSBFIRST, redoutputrow);
 digitalWrite(latchPin, HIGH);
 col++;
}

// called by timer2 void scroll() {

 if (!scrollNow)
  return;
 for (int m=1; m<COLS; m++)
 {
   for(int n=0; n<ROWS; n++)
     matrix[n*ROWS+m-1] = matrix[n*ROWS+m];
 }
 if (msgIndex >= msg.length())
   scrollNow = false;
 for (int j=0; j<COLS; j++)
 {
   int bit = 0;
   if (bitRead(alphabets[alphabetIndex][i], COLS-j-1))
     bit = green;
   matrix[j*ROWS+(COLS-1)] = bit;
 }
 i++;
 if (i > 5)
 {
   msgIndex++;
   alphabetIndex = msg.charAt(msgIndex) - 47;
   if (alphabetIndex < 0)
     alphabetIndex = 0;
   i = 0;
 }
}

// Create empty snake void resetSnake() {

 // Create empty snake
 for (int i=0; i<MATRIX; i++)  
 {
   snake[i] = -1;
   newsnake[i] = -1;
 }
 clearMatrix();
 // Add starting dot
 matrix[startingpoint] = orange;
 snakehead = startingpoint;
 snake[0] = snakehead;
 generateApple();
 matrix[apple] = green;
 direction = 1;
 applecount = 0;
}

// Moves snake void moveSnake() {

 if (millis() - lastMillis >= moveSpeed)
 {
   oldsnakehead = snakehead;
   switch(direction) {
case 0: // up if ((snakehead - ROWS) < 0) snakehead += (ROWS * (COLS - 1)); else snakehead -= ROWS; break; case 1: // right if ((snakehead - (snakehead % ROWS)) == (((snakehead+1) - (snakehead+1) % ROWS))) snakehead += 1; else snakehead = snakehead - (ROWS - 1); // to start of row break; case 2: // down if ((snakehead + ROWS) > ((ROWS * COLS - 1))) snakehead = snakehead % ROWS; else snakehead += ROWS; break; case 3: // left if (snakehead == 0) // exception for topleft, pixel 0 snakehead += (ROWS - 1); else

        {
          if ((snakehead - (snakehead % ROWS)) == (((snakehead-1) - (snakehead-1) % ROWS)))
snakehead -= 1;

          else
snakehead += (ROWS - 1); // end of row

        }
break; default: // wtf? break;

   }
   
   // Check if we have the apple
   if (snakehead == apple) 
   {
// Got it! // generateApple(); applecaught = 1;

   }
   
   for (int i=1; i<MATRIX; i++) 
   {
if (snake[i] == snakehead) endGame();

   }
 
   newsnake[0] = snakehead;
   for(int n=0; n<MATRIX-1; n++)
   {
if (snake[n] == -1)

       {
snaketail = snake[n-1]; if (applecaught == 0) newsnake[n] = -1; // undo last, we are moving on break; } newsnake[n+1] = snake[n];

   }
   
   for(int m=0; m<MATRIX; m++) {
snake[m] = newsnake[m];

   }
   if (applecaught == 1) 
   {
generateApple(); applecaught = 0;

       applecount++;
   }
   updateMatrix();
   lastMillis = millis();
 }
}

// Update snake in matrix void updateMatrix() {

 clearMatrix();
 for (int i=1; i<MATRIX; i++) {
   if (snake[i] == -1)
break;

   matrix[snake[i]] = red;
 }
 matrix[snakehead] = orange;
 matrix[apple] = green;
}

// Clear matrix (all LEDs off) void clearMatrix() {

 // Clear matrix
 for (int i=0; i<MATRIX; i++)  {
   matrix[i] = 0;
 }
}

// Generate random positon for apple void generateApple() {

 apple = random(MATRIX);
 for (int n=0; n<MATRIX; n++) 
 {
   if (snake[n] == apple)
generateApple();

 }
}

// Show number of catched apples void showResult() {

 clearMatrix();
 String msg = String(applecount);
 if (msg.length() == 1)
   msg = '0' + msg;
 int leftNumber = msg.charAt(0) - 48;
 int rightNumber = msg.charAt(1) - 48;
 for (int i=0; i<3; i++)
   for(int j=0; j<ROWS; j++)
   {
     int bit = 0;
     if (bitRead(numbers[leftNumber][i], ROWS-j-1))
       bit = red;
     matrix[j*COLS+i] = bit;
   }
 for (int i=0; i<3; i++)
   for(int j=0; j<ROWS; j++)
   {
     int bit = 0;
     if (bitRead(numbers[rightNumber][i], ROWS-j-1))
       bit = red;
     matrix[j*COLS+5+i] = bit;
   }
}

// Game over void endGame() {

 delay(500);
 apple = -1;
 for (int i=0; i<COLS; i++)
 {
   for (int n=0; n<ROWS; n++) 
matrix[n + (i * ROWS)] = green;

   delay(200);
 }
 delay(1000);
 showResult();
 delay(5000);
 resetSnake();
}

void loop() {

 bouncer1.update();
 bouncer2.update();
 bouncer3.update();
 bouncer4.update();
 if (bouncer1.read() == LOW) {
   if (button1value == HIGH) {
     buttonPressed = true;
     if (direction != 1)
       direction = 3; //LEFT
   }
 }
 button1value = bouncer1.read();
 if (bouncer2.read() == LOW) {
   if (button2value == HIGH) {
     buttonPressed = true;
     if (direction != 2)
       direction = 0; // UP
   }
 }
 button2value = bouncer2.read();
 if (bouncer3.read() == LOW) {
   if (button3value == HIGH) {
     buttonPressed = true;
     if (direction != 0)
        direction = 2; // DOWN
  }
 }
 button3value = bouncer3.read();
 if (bouncer4.read() == LOW) {
   if (button4value == HIGH) {
     buttonPressed = true;
     if (direction != 3)
       direction = 1; // RIGHT
   }
 }
 button4value = bouncer4.read();
 if (scrollOnce == false)
 {
   scrollOnce = true;
   msg = "Welcome  ";
   msgIndex = 0;
   alphabetIndex = msg.charAt(msgIndex) - 47;
   i = 0;
   scrollNow = true;
 }
 
 if (scrollNow == false)
 {
   if (apple == -1)
     resetSnake();
   moveSnake();
 }
 if (buttonPressed && scrollNow)
 {
   scrollOnce = true;
   scrollNow = false;
   buttonPressed = false;
 }
}

 

Video