Beispielprojekt – Snake

#include <U8g2lib.h>
#include <SPI.h>

#define LEDR 5
#define LEDY 6
#define LEDG 7
#define SPEAKER 15

#define KEY_RIGHT 2
#define KEY_DOWN 3
#define KEY_LEFT 4
#define KEY_UP 1
#define KEY_CENTER 0

#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4

U8G2_SH1106_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R3, 10, 8, 9);

int board[28][15];
int score, level, len, direction, px, py;

void setup(void){
  u8g2.begin();

  u8g2.setContrast(31);
  u8g2.clearBuffer();
  u8g2.sendBuffer();

  pinMode(KEY_RIGHT, INPUT_PULLUP);
  pinMode(KEY_DOWN, INPUT_PULLUP);
  pinMode(KEY_LEFT, INPUT_PULLUP);
  pinMode(KEY_UP, INPUT_PULLUP);
  pinMode(KEY_CENTER, INPUT_PULLUP);

  pinMode(SPEAKER, OUTPUT);
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDY, OUTPUT);
  u8g2.setFont(u8g2_font_smart_patrol_nbp_tr);
  u8g2.setFontDirection(1);
  while (true){
    initialize();
    play();
  }
}

void putApple(){
  int rx = random(0, 28);
  int ry = random(0, 15);

  while (board[rx][ry] != 0){
    rx = random(0, 28);
    ry = random(0, 15);
  }
  board[rx][ry] = -1;
}

void initialize(){
  score = 0;
  level = 0;
  len = 3;
  px = 13;
  py = 8;

  for (int ix = 0; ix < 28; ix++){
    for (int iy = 0; iy < 15; iy++){
      board[ix][iy] = 0;
    }
  }
}

void writeScore(int score) {
  u8g2.setFont( u8g2_font_4x6_mr );
  u8g2.setCursor(57, 119);
  u8g2.println("SC");
  u8g2.setCursor(51, 119);
  u8g2.println("OR");
  u8g2.setCursor(45, 121);
  u8g2.println("E");
  u8g2.setFont(u8g2_font_smart_patrol_nbp_tr);
  int ypos = 0;
  for (int i = 0; i < 4; i++){
    int digit = score % 10;
    score /= 10;
    char cstr[16];
    itoa(digit, cstr, 10);
    u8g2.setCursor(ypos, 122 - u8g2.getStrWidth(cstr) / 2);
    u8g2.println(cstr);
    ypos += 11;
  }
}

void draw(){
  u8g2.clearBuffer();
  u8g2.drawFrame(0, 0, 64, 116);
  for (int ix = 0; ix < 28; ix++){
    for (int iy = 0; iy < 15; iy++){ if (board[ix][iy] > 0){
        u8g2.drawFrame(iy * 4 + 2, ix * 4 + 2, 4, 4);
        if (board[ix][iy] == len){
          u8g2.drawFrame(iy * 4 + 3, ix * 4 + 3, 2, 2);
        }
      }
      else if (board[ix][iy] == -1){
        u8g2.drawFrame(iy * 4 + 2, ix * 4 + 3, 4, 2);
        u8g2.drawFrame(iy * 4 + 3, ix * 4 + 2, 2, 4);
      }
    }
  }
  writeScore(len - 3);
  u8g2.sendBuffer();
}

bool crash(int dir){
  if (dir == UP && (py == 14 || board[px][py + 1] > 0)){
    return true;
  }
  
  if (dir == DOWN && (py == 0 || board[px][py - 1] > 0)){
    return true;
  }

  if (dir == LEFT && (px == 0 || board[px - 1][py] > 0)){
    return true;
  }

  if (dir == RIGHT && (px == 27 || board[px + 1][py] > 0)){
    return true;
  }

  return false;
}

void step(){
  for (int ix = 0; ix < 28; ix++){
    for (int iy = 0; iy < 15; iy++){ if (board[ix][iy] > 0){
        board[ix][iy] = board[ix][iy] - 1;
      }
    }
  }
}

void play(){
  uint32_t lastTime = 0;
  int lastDir = 0;
  direction = random(1, 5);
  putApple();

  while (true){
    while (millis() < lastTime + 60){
      if (digitalRead(KEY_RIGHT) == LOW && lastDir != LEFT){
        direction = RIGHT;
      }
      if (digitalRead(KEY_LEFT) == LOW && lastDir != RIGHT){
        direction = LEFT;
      }
      if (digitalRead(KEY_DOWN) == LOW && lastDir != UP){
        direction = DOWN;
      }
      if (digitalRead(KEY_UP) == LOW && lastDir != DOWN){
        direction = UP;
      }
    }

    lastDir = direction;

    if (!crash(direction))
    {
      if (direction == LEFT){
        px--;
      }
      if (direction == RIGHT){
        px++;
      }
      if (direction == DOWN){
        py--;
      }
      if (direction == UP){
        py++;
      }
    } else {
      u8g2.setDrawColor(0);
      u8g2.drawBox(1, 1, 62, 114);
      u8g2.setDrawColor(1);

      u8g2.setCursor(40, 58 - u8g2.getStrWidth("YOUR") / 2);
      u8g2.println("YOUR");
      u8g2.setCursor(25, 58 - u8g2.getStrWidth("SCORE") / 2);
      u8g2.println("SCORE");
      char cstr[16];
      itoa(len - 3, cstr, 10);
      u8g2.setCursor(10, 58 - u8g2.getStrWidth(cstr) / 2);
      u8g2.println(cstr);
      u8g2.sendBuffer();
      delay(250);

      while (digitalRead(KEY_CENTER) == HIGH){}
      break;
    }

    if (board[px][py] == -1){
      tone(SPEAKER, 6500, 10);
      putApple();
      len++;
    }

    board[px][py] = len;

    draw();
    step();

    lastTime = millis();
  }
}

void loop() {}