Table of Contents

Snake

Autor

Nistor Andreea Iuliana 333CB

Introducere

Proiectul constă în implementarea jocului Snake pe un LCD. Am vrut sa fie cât mai aproape de jocul original, astfel că am ales să păstrez controlul șarpelui din 4 butoane pentru stânga, dreapta, sus si jos. Scopul jocului este ca șarpele să crească cât mai mare fără să atingă marginile sau pe el, consumând hrana care apare random pe ecran.

De asemenea, atunci când player-ul pierde, i se da posibilitatea să își scrie numele pentru a-l trece intr-o listă de highscores. Un al cincelea buton este folosit pentru a schimba state-urile curente ale jocului (main page → game play → game over → check highscore & set name → highscores → main page).

Scopul proiectului este implementarea unui joc clasic lansat în 1976 pentru însușirea cunoștințelor dobândite la cursul de Proiectarea cu Microprocesoare.

Descriere generală

Modul de funcționare este simplu: jucătorul va controla din cele 4 butoane și va putea urmări pe LCD mișcările șarpelui și apariția random a hranei.

Hardware Design

Listă de piese:

Schema electrică

Software Design

Mediul de dezvoltare folosit este Arduino IDE, schema bloc a fost realizata in Lucidchart, iar schema electrica in EAGLE. De asemenea am folosit librăriile LiquidCrystal.h pentru LCD si EEPROM.h pentru memoria EEPROM.

Variabile si utilizare

Definire pini și macro-uri:

Variabile globale:

Funcții

setup()

void setup(){
  pinMode(redPin,OUTPUT);
  pinMode(greenPin,OUTPUT);
  pinMode(bluePin,OUTPUT);
  pinMode(BUTTON_GameState, INPUT_PULLUP);
  pinMode(BUTTON_UP, INPUT_PULLUP);
  pinMode(BUTTON_RIGHT, INPUT_PULLUP);
  pinMode(BUTTON_LEFT, INPUT_PULLUP);
  pinMode(BUTTON_DOWN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON_GameState), BtnInterrupt, FALLING); 
  graphic_generate_characters();
  Game_MAIN();
  gameState = GAME_MENU;
}

Definesc:

loop()

if(Interrupt){ // verifică dacă a apărut o întrerupere
       delay(5*DEBOUNCE_DURATION); // un delay cu rol de debounce 
       switch(gameState){...} // schimbă starea curentă a jocului prematur la apăsarea butonului GameState
 Interrupt = false;} // resteaza valoarea setată in întrerupere până la următoarea întrerupere
if(digitalRead(BUTTON_UP) == pressed){ // verifică dacă butonul respectiv a fost apelat
    if(debounce_activate_edge(&debCountBUTTON_UP)){ -// verifică debounce-ul
      snakeDirection=SNAKE_UP; // schimbă direcția snake-ului
    }
}else{
    debounce_deactivate(&debCountBUTTON_UP); // în cazul în care butonul nu a fost apăsat, resetează timer-ul de debounce
}

Același tipar de verificare este apelat pentru restul butoanelor care definesc mișcarea snake-ului.

if(millis()-lastGameUpdateTick > gameUpdateInterval){
  game_calculate_logic();
  game_calculate_display();
  graphic_clear();
  rgb_color();
  lastGameUpdateTick = millis();
} // verifica constant dacă jocul trebuie să-ți dea refresh să recalculeze starea jocului, culoarea led-ului, dimensiunea, pozitia snake-ului și a mărului

Rezultate Obţinute

Demo youtube: https://www.youtube.com/watch?v=DwJfF1_lE9Y

Concluzii

Simpla idee că aș putea realiza un joc singură m-a motivat să duc până la capăt acest proiect. Consider că a fost un mod captivant prin care am aplicat cunoștințe dobândite în cadrul cursului de PM.

Download

proiect_pm.zip

Jurnal

Bibliografie/Resurse

https://ocw.cs.pub.ro/courses/pm/lab/lab3-2022

https://www.arduino.cc/en/Tutorial/BuiltInExamples/Debounce

https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt

https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf

Export to PDF