This is an old revision of the document!


Snake Game

Autor

Nume: Olaru Alexandru
Grupa: 336CA

Introducere

Fiind pasionat de jocuri video și de console, m-am gândit să retrăiesc bucuria din copilărie atunci când mă jucam Snake pe diversele mini-console de la acea vreme. Așadar, proiectul reprezintă un joc Snake, ce incearcă să fie cât mai asemănător cu un joc pe o consolă portabilă.

Descriere generală

Schema bloc este compusă din urmatoarele componente: un Arduino Uno, o matrice de leduri 8×8, un potențiometru, un buzzer și un joystick. Matricea de leduri stă in locul ecranului, pe care m-am gândit să îl înlocuiesc, oferindu-i jocului un aspect mai retro. Ledurile aprinse vor semnifica atât șarpele, cât și merele la care acesta va trebui să ajungă. Joystick-ul reprezintă singura modalitate de input a utilizatorului, prin care acesta poate mișca șarpele in 4 direcții: sus, jos, stânga și dreapta. Nu în ultimul rând, prin intermediul potențiometrului se poate regla viteza de joc, iar buzzer-ul este post de difuzor.

Hardware Design

Lista de piese folosite:

  • Arduino Uno
  • Breadboard
  • Modul joystick compatibil Arduino
  • Matrice 8×8 leduri OKY3523
  • Buzzer activ OKY0151
  • Potențiometru rotativ OKY0107

Schema electrica:

Matrice Led:

  • VCC → 5V
  • GND → GND
  • DIN → D12
  • CS → D11
  • CLK → D10

Modul Joystick:

  • GND → GND
  • VCC → 5V
  • VRX → A2
  • VRY → A3
  • SW → D2

Buzzer:

  • - → GND
  • + → D8

Potentiometer:

  • VCC → 5V
  • VOUT → A5
  • GND → GND

proiectsnakeolaru.jpg

Software Design

Descrierea codului aplicaţiei:

  • Mediul de dezvoltare: Arduino IDE
  • Bibliotecile şi sursele 3rd-party folosite: https://github.com/wayoda/LedControl
  • Surse proprii: fișierul “Snake_Game.ino” și header-ul “Snake.h”

Structura codului arată astfel:

void setup() {
   initialize();
   display_snake_message(message_snake);
}
void loop() {
   /* Generate food on the display */
   generate_food();
   /* Scan joystick input and move the snake */
   scan_input();
   /* Snake movement */
   move_snake();
   /* Check and handle game over situation */
   check_game_over();
}

Implementare:

  • Funcția initialize() inițializeaza variabilele ce se ocupă cu stările jocului, configureaza ADC(Analog-to-Digital Converter), ce va fi folosit pentru a citi inputul de la joystick, precum și matricea de led-uri.
  • Funcția display_snake_message(message_snake) va afișa un text dinamic atunci când ”consola” va fi pornită. Acest text va dispărea atunci când se înregistrează un input de la joystick (fie o mișcare a manetei, fie o apăsare a butonului acesteia).
  • Funcția generate_food() generează mâncarea șarpelui într-un loc random (unul din cele 64 led-uri de pe matrice), care este valid și care nu este ocupat de șarpe. Aceasta se va genera, schimbându-și locul, doar după ce șarpele o va mânca.
  • Funcția scan_input() va citi input-ul de la joystick, calculând direcția de deplasare a șarpelui. Aceasta se va ocupa și de viteza jocului, care poate fi setată cu ajutorul potențiometrului (cu cât viteza este mai mică, cu atât funcția se termină mai greu, dictând intervalul de timp în care se aprind și se sting led-urile).
  • Funcția move_snake() este cea care controlează locația în care se află șarpele, în funcție de direcția acestuia. Aceasta tratează cazurile în care șarpele iși mușcă propria coadă, mănâncă mărul, trece prin marginile ”display-ului” și apare din părțile opuse, și se ocupă de aprinderea corespunzătoare a led-urilor în funcție de poziția corpului șarpelui. Atunci când șarpele va mânca mărul, un sunet scurt va fi emis de către buzzer.
  • Funcția check_game_over() verifica dacă jocul este încheiat, caz în care va afișa un mesaj de ”GAME OVER”. Buzzer-ul va emite un sunet ceva mai lung, pe o tonalitate mai joasă ,iar variabilele de joc vor fi resetate, așteptând input de la joystick pentru ca jocul sa poată fi jucat din nou.

Citirea input-ului de la joystick (valorile X si Y) este făcută folosind ADC:

uint8_t adc_read(uint8_t pin) {
  /* Select ADC channel (pin) for conversion */
  ADMUX = (ADMUX & 0xF0) | (pin & 0x0F);
  /* Start the conversion */
  ADCSRA |= (1 << ADSC);
  /* Wait for the conversion to complete */
  while (ADCSRA & (1 << ADSC));
  /* Return the result */
  return ADCH;
}

Pentru a aprinde și a stinge led-urile matricei, am folosit funcții din biblioteca https://github.com/wayoda/LedControl, după mai multe încercări de a implementa această funcționalitate ”de mână”, folosind SPI (Serial Peripheral Interface), care este de asemenea folosit și în funcțiile bibliotecii, într-o modalitate asemanătoare cu cea prezentată mai jos:

void send_data(uint8_t address, uint8_t value) {  
  digitalWrite(CS, LOW);
  /* Send address */
  SPI.transfer(address);
  /* Send value */
  SPI.transfer(value);
  /* Finish transfer */
  digitalWrite(CS, HIGH);
}

Astfel, pinul Chip-Select (CS) este configurat, trimițându-se mai apoi prin SPI adresa registrului lui MAX7219 al matricei de leduri, precum și valoarea dorită. Dacă se dorește aprinderea sau stingerea led-urilor, conform specificațiilor din datasheet (https://www.analog.com/media/en/technical-documentation/data-sheets/max7219-max7221.pdf), adresa va fi un număr de la 1 la 8, reprezentând linia din matrice pe care se vor aplica modificări, iar valoarea un număr de la 0 la 255, indicând ce led-uri vor fi aprinse, respectiv stinse.

Rezultate Obţinute

Care au fost rezultatele obţinute în urma realizării proiectului vostru. Rezultatele obținute în urma realizării proiectului se pot observa în următorul demo: https://www.youtube.com/watch?v=BKTVWNCKRaY&t=9s&ab_channel=AlexandruOlaru

Concluzii

Download

O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului: surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-).

Fişierele se încarcă pe wiki folosind facilitatea Add Images or other files. Namespace-ul în care se încarcă fişierele este de tipul :pm:prj20??:c? sau :pm:prj20??:c?:nume_student (dacă este cazul). Exemplu: Dumitru Alin, 331CC → :pm:prj2009:cc:dumitru_alin.

Jurnal

Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului.

Bibliografie/Resurse

pm/prj2023/apredescu/snakegame.1685132469.txt.gz · Last modified: 2023/05/26 23:21 by alexandru.olaru0409
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0