niedziela, 18 maja
Shadow

Kultowy Snake na Arduino

Zapewne większość z was pamięta już można powiedzieć „kultową” grę Snake. Była to gra fabrycznie zainstalowana w telefonach Nokia np. 3210, 3310 czy innych a było ich sporo. Zatem dziś pokaże wam jak zbudować mini konsolę. Dzięki temu część z was poczuje jak to przysłowiowo kiedyś było.

Potrzebne komponenty:

  • Arduino np. nano
  • wyświetlacz OLED SSD1306
  • moduł dwuosiowego joysticka analogowego
  • płytka stykowa lub wersja na pająka

Schemat połączeń

snake arduino

Zanim przejdziemy do kodu programu upewnij się, że zainstalowałeś niezbędną bibliotekę Adafruit_SSD1306 do obsługi wyświetlacza OLED.

Kod programu

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 oled(128, 64, &Wire, -1);

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

//STICKBOX Pin
#define pinX  A0
#define pinY  A1

int valueX = 0;
int valueY = 0;
unsigned char keyValue = 0;


//Snake Value

const uint8_t block[] PROGMEM = {
  0xf0, //B1111000
  0xb0, //B1011000
  0xd0, //B1101000
  0xf0, //B1111000
};


uint8_t snake_head_x = 4;
uint8_t snake_head_y = 4;
uint8_t x[100];
uint8_t y[100];
uint8_t snake_len = 2;
uint8_t snake_dir = RIGHT;

uint8_t food_x;
uint8_t food_y;
bool food_eaten = true;

bool game_over = false;
int score = 0;
int level = 1;
int snake_speed = 150;
int i;

void keyScan(void)
{
  static unsigned char keyUp = 1;

  valueX = analogRead(pinX);
  valueY = analogRead(pinY);

  if (keyUp && ((valueX <= 10) || (valueX >= 1010) || (valueY <= 10) || (valueY >= 1010)))
  {
    delay(10);
    keyUp = 0;
    if (valueX <= 10)
    {
      if (snake_dir != UP)
      {
        snake_dir = DOWN;
      }
    }
    else if (valueX >= 1010)
    {
      if (snake_dir != DOWN)
      {
        snake_dir = UP;
      }
    }
    else if (valueY <= 10)
    {
      if (snake_dir != RIGHT)
      {
        snake_dir = LEFT;
      }
    }
    else if (valueY >= 1010)
    {
      if (snake_dir != LEFT)
      {
        snake_dir = RIGHT;
      }
    }
  } else if ((valueX > 10) && (valueX < 1010) && (valueY > 10) && (valueY < 1010))keyUp = 1;
  return 0;
}

void draw_snake(int x, int y)
{
  oled.drawBitmap(x, y, block, 4, 4, 1);
}

void show_score(int x, int y, int data)
{
  oled.setCursor(x, y);
  oled.println(data);

}

void screen(void)
{
  oled.clearDisplay();
  oled.setTextSize(1); 
  oled.drawRect(0, 1, 102, 62, 1);
  oled.drawRect(0, 0, 102, 64, 1);
  oled.setCursor(104, 12);
  oled.println("LEVE");
  oled.setCursor(104, 40);
  oled.println("SCOR");

  show_score(110, 25, level);
  show_score(110, 53, score);

  for (i = 0; i < snake_len; i++)
  {
    draw_snake(x[i], y[i]);
  }

  draw_snake(food_x, food_y);

  oled.display();

}

void draw_food(void)
{
  int food_out = 0;
  if (food_eaten)
  {
    while (food_out == 0)
    {
      food_out = 1;

      food_x = (uint8_t)(random(4, 100) / 4) * 4;
      food_y = (uint8_t)(random(4, 60) / 4) * 4;

      for (int i = snake_len - 1; i > 0; i--) 
      {
        if (food_x == x[i] && food_y == y[i])
        {
          food_out = 0;
        }
      }
    }
  }

  food_eaten = false;
}

void snake_move(void)
{
  switch (snake_dir) {
    case RIGHT:
      snake_head_x += 4;
      break;
    case UP:
      snake_head_y -= 4;
      break;
    case LEFT:
      snake_head_x -= 4;
      break;
    case DOWN:
      snake_head_y += 4;
      break;
  }

  if ((snake_head_x == food_x) && (snake_head_y == food_y))
  {
    food_eaten = true;
    snake_len++;
    score++;
    level = score / 5 + 1;
    snake_speed -= level;
  }

  for (i = snake_len - 1; i > 0; i--)
  {
    x[i] = x[i - 1];
    y[i] = y[i - 1];
  }
  x[0] = snake_head_x;
  y[0] = snake_head_y;

  check_snake_die();
}

void draw_game_over()
{
  oled.clearDisplay();
  oled.setTextSize(2); 
  oled.setCursor(10, 10);

  oled.println("GAME OVER");
  oled.setTextSize(1); 
  oled.setCursor(30, 35);
  oled.println("LEVE:");
  oled.setCursor(30, 55);
  oled.println("SCOR:");

  show_score(80, 35, level);
  show_score(80, 55, score);

  oled.display();
}



void check_snake_die(void)
{
  
  if (snake_head_x < 4 || snake_head_x > 96 || snake_head_y < 1 || snake_head_y > 56)
  {
    game_over = true;
  }

  //自己吃自己
  if (snake_len > 4)
  {
    for (int i = 1; i < snake_len; i++)
    {
      if (snake_head_x == x[i] && snake_head_y == y[i])
      {
        game_over = true;
      }
    }
  }
}


void setup()
{
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  oled.setTextColor(WHITE);
  randomSeed(analogRead(3));
}


void loop()
{
  if (game_over)
  {
    draw_game_over();
  } else {
    keyScan();
    snake_move();
    draw_food();
    screen();
  }
  delay(snake_speed);
}

Kod do pobrania -> pobierz

5/5 - (1 ocena/y)

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *


This site uses Akismet to reduce spam. Learn how your comment data is processed.