Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2022:arosca:snakegamewithgyroscope [2022/05/23 20:25]
gabriel.saru [Software Design]
pm:prj2022:arosca:snakegamewithgyroscope [2022/05/27 19:29] (current)
gabriel.saru [Download]
Line 64: Line 64:
 În codul meu am setat lungimea maximă a șarpelui la 64, care este întreaga matrice LED. Am făcut asta pentru că am vrut ca jocul să se termine doar dacă șarpele a murit și nu dacă a ajuns la o anumită lungime. În codul meu am setat lungimea maximă a șarpelui la 64, care este întreaga matrice LED. Am făcut asta pentru că am vrut ca jocul să se termine doar dacă șarpele a murit și nu dacă a ajuns la o anumită lungime.
  
-''​asd''​+Un mic rezumat in ceea ce fac functiile:​ 
 + 
 +  *    void playGame() ​ --> această funcție va porni jocul 
 +  *    void draw() ​ --> aceasta functie va apela funcțiile pentru a desena șarpele și ținta 
 +  *    void drawSnake() --> aceasta functie va desena sarpele 
 +  *    void drawTarget() --> aceasta functie va atrage ținta 
 +  *    boolean inPlayField(int x, int y) --> va stabili terenul de joc pentru țintă și șarpe pentru a se spawna pe harta 
 +  *    void makeTarget() --> aceasta functie va alege o valoare aleatorie și va stabili ținta 
 +  *    boolean isPartOfSnake(int x, int y) --> ​ aceasta functie se va citi dacă valoarea face parte sau nu din șarpe. 
 +  *    void makeSnake() --> aceasta functie va stabili valorile șarpelui 
 +  *    void moveSnake() --> această funcție va muta șarpele în funcție de accelerometru 
 +  *    void gameOver() --> aceasta functie va afișa spectacolul de lumini și va nota după terminarea jocului 
 + 
 +==== Cod Sursa ==== 
 + 
 +<​code>​  
 + 
 +#include <​SparkFun_MMA8452Q.h>​ 
 + 
 + 
 +//First we need to set up some libraries so that we can use all the parts we want 
 +#include <​Wire.h>​ // we need this to use I2C which is a requirement of the  
 +// acceleromter and LED matrix 
 +//#include <​SFE_MMA8452Q.h>​ // this will include the library so we can use the accelerometer 
 + 
 +//these two libraries are so we can use the LED matrix 
 +#include "​Adafruit_LEDBackpack.h"​ 
 +#include "​Adafruit_GFX.h"​ 
 + 
 +// these three libraries are needed to connect the Arduino with the internet and Twitter. 
 +#include <​SPI.h>​ // needed in Arduino 0019 or later 
 +#include <​Ethernet.h>​ 
 +#include <​EEPROM.h>​ // this will allow us to store memory on the Arduino. 
 + 
 +//Now we need to set up some features for our accelerometer 
 +MMA8452Q accel; 
 + 
 +//Now we need to set up some features for our LED matrix 
 +Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();​ 
 + 
 +//Now to set up our Ethernet shield and Twitter 
 + 
 +byte mac[] { 0x90, 0xA2, 0xDA, 0x0D, 0x14, 0x79 }; 
 +//This is where you enter the information for your Ethernet shield 
 +//You should find your code on a label on the bottom of the shield 
 +//You want to enter it 0x## where ## is the information found on your label. 
 + 
 +//If you want to specify a specific a IP address you can enter it like seen below 
 +// byte ip[] = { 10, 3, 19, 73 }; 
 + 
 +//Specify your Token so we can use your Twitter 
 +//You can get your token from (http://​arduino-tweet.appspot.com/​) 
 +//this is my token, make sure to use your own for it to show up on your Twitter news feed 
 + 
 +//this will set up a message which we will use later when we want to post to Twitter 
 +char msg[70]; 
 + 
 +//Now we need to set up some variables 
 +const int powerButton = 7; 
 +const int sendButton = 6; 
 +int resetButton;​ 
 +const int maxSnake = 64; //this is the maximum length the snake can reach 
 +int snakeX[maxSnake];​ // this is the x coordinate of the snake 
 +int snakeY[maxSnake];​ // this is the y coordinate of the snake 
 +int snakeLength = 1; // this is the starting length of the snake 
 +int targetX; //this is the x coordinate of the item we are going after 
 +int targetY; //the y coordinate of the item we are going after 
 +unsigned long targetPrevTime = 0; //these will be used to help with the timing of the target 
 +unsigned long targetBlinkTime = 1000 / 250; 
 +int targetLED = LED_GREEN;​ 
 +unsigned long prevTime = 0; 
 +unsigned long delayTime = 500; 
 +int score = 0; 
 + 
 +int8_t collision = 0; 
 + 
 +// these variables will be used to make our switch work properly 
 +int mode = 0; 
 +const int NUMMODES = 3; 
 + 
 +int storedScore = 0; //this will be used to store our score inthe EEPROM 
 + 
 +static int prevDirection;​ //this will be used to store the previous direction the snake was moving in 
 + 
 +void setup() { 
 +  //Set up our pins as inputs 
 +  pinMode(powerButton,​ INPUT); 
 +  pinMode(sendButton,​ INPUT); 
 +  pinMode(resetButton,​ INPUT); 
 + 
 +  Serial.begin(9600);​ 
 + 
 +  matrix.begin(0x70);​ //pass in the address, set up the matrix 
 + 
 +  accel.init();​ //this will intiate the accelerometer 
 +  randomSeed(analogRead(A0));​ //we use this so that we will be able to 
 +  //make a random pixel light up that will serve as the target our snake is after. 
 + 
 +  makeSnake();​ //this will call a function to set up where our snake will start on the matrix 
 +  makeTarget();​ // this will call a function to set up where our target will be on the matrix. 
 +
 + 
 +void loop() { 
 +  // this will clear the display just in case something else was on it before 
 +  matrix.clear();​ 
 +  matrix.writeDisplay();​ 
 + 
 +  static int prevPowerState = 0; //this will ensure we read only the button push, and not how long it is pushed. 
 +  int powerButtonState = digitalRead(powerButton);​ //this will moniter the state of the button 
 +  if ((powerButtonState == HIGH) && (prevPowerState == LOW)) { 
 +    mode = (mode + 1) % NUMMODES; 
 +  } 
 +  prevPowerState = powerButtonState;​ 
 + 
 +  switch (mode) { 
 +    case 0: //if the button has not been pushed nothing happens 
 +      //​Serial.println("​OFF"​);​ debug to make sure switch works properly 
 +      break; 
 +    case 1: //if the button is pushed the game starts 
 +      playGame();​ 
 +      break; 
 +    case 2: 
 +      gameOver();​ 
 +      break; 
 +  } 
 + 
 + 
 +  int sendButtonState = digitalRead(sendButton);​ //this will send a Tweet of the score by pushing the red button 
 +  if (sendButtonState == HIGH) { 
 +  } 
 +
 + 
 +void playGame() { // this funciton will start up the game 
 + 
 +  unsigned long currentTime = millis(); 
 +  if (currentTime - prevTime >= delayTime) { 
 +    nextstep();​ 
 +    prevTime = currentTime;​ 
 +  } 
 +  draw(); // this will call the draw function which will draw the snake and target 
 +
 + 
 +void nextstep() { 
 +  for (int i = snakeLength - 1; i > 0; i--) { 
 +    snakeX[i] = snakeX[i - 1]; 
 +    snakeY[i] = snakeY[i - 1]; 
 +  } 
 + 
 +  for (int8_t h = 3; h <= snakeLength;​ h++) { // this will monitor if the snake's head is colliding with another part 
 +    // of the snake. we use 3 because it is basically impossible for the snake to hit itself before then. 
 +    if ((snakeX[0] == snakeX[h]) && (snakeY[0] == snakeY[h])) 
 +    { 
 +      collision = 1; // if it is then it will send a message of collision. 
 +    } 
 +  } 
 +  Serial.print("​Collision:"​);​ //used for debugging to ensure the collision detection worked 
 +  Serial.println(collision);​ 
 + 
 +  if ((inPlayField(snakeX[0],​ snakeY[0])) && collision == 0) { // if the snake is in the playing field 
 +    // or not colliding with itself then we will be able to continue to play 
 +    moveSnake();​ //this will call a function to move the snake 
 + 
 +    if ((snakeX[0] == targetX) && (snakeY[0] == targetY)) { //this will read if the snake is on the target 
 +      snakeLength++;​ //if it is it will gain a length of one 
 +      score++; // and the score will increase by one 
 +      Serial.print("​Score:​ "); // the score will then be written on the serial monitor 
 +      Serial.println(score);​ 
 +      if (snakeLength < maxSnake) { // if the snake is less than the maxium lenght 
 +        makeTarget();​ //then we will make a new target to go after 
 +      } 
 +      else { 
 +        targetX = targetY = -1; //if it is not less than the max, then we will not 
 +        //make any more targets 
 +      } 
 +    } 
 +  } 
 +  else { // if it is not in the play field or it collids with itself then the game is over. 
 +    mode = 2; 
 +  } 
 +
 + 
 +void draw () { //this will call the functions to draw the snake and target 
 +  matrix.clear();​ 
 +  drawSnake();​ 
 +  drawTarget();​ 
 +  matrix.writeDisplay();​ 
 +
 + 
 +void drawSnake() { //this will draw the snake 
 +  for ( int i = 0; i < snakeLength;​ i++) { 
 +    matrix.drawPixel(snakeX[i],​ snakeY[i], LED_GREEN);​ 
 +  } 
 +
 + 
 +void drawTarget() { //this will draw the target 
 +  if (inPlayField(targetX,​ targetY)) { 
 +    unsigned long currenttime = millis(); 
 +    if (currenttime - targetPrevTime >= targetBlinkTime) { 
 +      targetLED = (targetLED == LED_RED) ? LED_OFF : LED_RED; 
 +      targetPrevTime = currenttime;​ 
 +    } 
 +    matrix.drawPixel(targetX,​ targetY, targetLED);​ 
 +  } 
 +
 + 
 +boolean inPlayField(int x, int y) { //this will set up the playing field for the target 
 +  // and snake to spawn in. 
 +  return (x >= 0) && (x < 8) && (y >= 0) && (y < 8); 
 +
 + 
 +void makeTarget() { //this will choose a random value and set up the target 
 +  int x; 
 +  int y; 
 +  x = random(0, 8); 
 +  y = random(0, 8); 
 +  while (isPartOfSnake(x,​ y)) { //here it will check if the target is part of the snake 
 +    x = random(0, 8); // if it is it will choose a new random point and thus continue the game 
 +    y = random(0, 8); 
 +  } 
 +  targetX = x; 
 +  targetY = y; 
 +
 + 
 +boolean isPartOfSnake(int x, int y) { //this will read if the value is part of the snake or not. 
 +  for (int i = 0; i < snakeLength - 1; i++) { 
 +    if ((x == snakeX[i]) && (y == snakeY[i])) { 
 +      return true; //if it is it will return true 
 +    } 
 +  } 
 +  return false; // if it is not part of the snake it will return false 
 +
 + 
 + 
 +void makeSnake() { //this will set up the values of the snake 
 +   
 +  snakeX[0] = 3; 
 +  snakeY[0] = 4; 
 +   
 +  for (int i = 1; i < maxSnake; i++) { 
 +    snakeX[i] = snakeY[i] = -1; 
 +  } 
 +
 + 
 +void moveSnake() { // this function will move the snake according to the accelerometer 
 +  if (accel.available()) { 
 +    accel.read();​ //this will read the values of the accelerometer 
 +    Serial.print("​x:​ "); 
 +    Serial.print(accel.cx,​ 3); 
 +    Serial.print("​\t"​);​ 
 +    Serial.print("​y:​ "); 
 +    Serial.print(accel.cy,​ 3); 
 +    Serial.print("​\t"​);​ 
 +    Serial.print("​z:​ "); 
 +    Serial.print(accel.cz,​ 3); 
 +    Serial.print("​\t"​);​ 
 +    Serial.println(prevDirection);​ 
 +    float restingX = 0; //the accelerometer at rest 
 +    float restingY = 0; 
 +    float threshold = 0.350; //how much it should be tilted to move the snake. 
 + 
 + 
 +    Serial.println(accel.cy - restingY);​ 
 +    Serial.println(accel.cx - restingX);​ 
 +    Serial.println(abs(accel.cx - restingX));​ 
 + 
 + 
 +    if (((accel.cy - restingY) > threshold) && (abs(accel.cx - restingX) < threshold)) { //if the accelerometer is tilted left 
 +      Serial.println("​Left"​);​ 
 +      snakeY[0] = snakeY[0] + 1; // the snake will move to the left. 
 +      prevDirection = 1; 
 +    } 
 + 
 +    if (((accel.cy - restingY) < -threshold) && (abs(accel.cx - restingX) < threshold)) { //if the accelerometer is tilted right 
 +      Serial.println("​Right"​);​ 
 +      snakeY[0] = snakeY[0] - 1; // snake will move to the right 
 +      prevDirection = 2; 
 +    } 
 + 
 +    if (((accel.cx - restingX) > threshold) && (abs(accel.cy - restingY) < threshold)) { //if the accelerometer is tilted up 
 +      Serial.println("​Up"​);​ 
 +      snakeX[0] = snakeX[0] - 1; // the snake will move up 
 +      prevDirection = 3; 
 +    } 
 + 
 +    if (((accel.cx - restingX) < -threshold) && (abs(accel.cy - restingY) < threshold)) { //if the accelerometer is tilted down 
 +      Serial.println("​Down"​);​ 
 +      snakeX[0] = snakeX[0] + 1; // it will move the snake down 
 +      prevDirection = 4; 
 +    } 
 + 
 +    if ((-threshold < accel.cx) && (accel.cx < threshold) && (-threshold < accel.cy) && (accel.cy < threshold)) { 
 +      if (prevDirection == 1) { 
 +        snakeY[0] = snakeY[0] + 1; 
 +      } 
 +      if (prevDirection == 2) { 
 +        snakeY[0] = snakeY[0] - 1; 
 +      } 
 +      if (prevDirection == 3) { 
 +        snakeX[0] = snakeX[0] - 1; 
 +      } 
 +      if (prevDirection == 4) { 
 +        snakeX[0] = snakeX[0] + 1; 
 +      } 
 +    } 
 +  } 
 +
 + 
 +void gameOver() { //this will display the lightshow and score after the game is over 
 +  Serial.println("​Game Over"​);​ 
 +  Serial.print("​Final Score: "); 
 +  Serial.println(score);​ 
 +  EEPROM.write (storedScore,​ score); 
 + 
 + 
 +  matrix.clear();​ 
 +  matrix.drawPixel(3,​ 4, LED_YELLOW);​ //start a spiral lightshow from the middle to edge 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(3,​ 4, 4, 4, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(4,​ 4, 4, 3, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(4,​ 3, 2, 3, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(2,​ 3, 2, 5, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(2,​ 5, 5, 5, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(5,​ 5, 5, 2, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(5,​ 2, 1, 2, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(1,​ 2, 1, 6, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(1,​ 6, 6, 6, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(6,​ 6, 6, 1, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(6,​ 1, 0, 1, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(0,​ 1, 0, 7, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(0,​ 7, 7, 7, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(7,​ 7, 7, 0, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.drawLine(7,​ 0, 0, 0, LED_YELLOW);​ 
 +  matrix.writeDisplay();​ 
 +  delay(100);​ 
 + 
 +  matrix.setTextWrap(false);​ //this will display our score on our matrix 
 +  matrix.setTextSize(1);​ 
 +  matrix.setTextColor(LED_YELLOW);​ 
 +  matrix.setRotation(3);​ 
 +   
 +  for (int8_t x = 7; x >= -36; x--) { 
 +    matrix.clear();​ 
 +    matrix.setCursor(x,​ 0); 
 +    matrix.print(score);​ 
 +    matrix.writeDisplay();​ 
 +    delay (100); 
 +  } 
 +
 + 
 + 
 +</​code>​
  
 ====  Rezultate Obţinute ====  ====  Rezultate Obţinute ==== 
  
-TBA+Implementarea proiectului este urmatoarea:
  
 +{{:​pm/​prj2022/​arosca/​rezultat_sgabriel_1_resized.jpg}}
 +{{:​pm/​prj2022/​arosca/​rezultat_sgabriel_2_resized.jpg}}
  
 ===== Concluzii ===== ===== Concluzii =====
-TBA 
  
 +Consider ca proiectul de fata implementat,​ este destul de util pentru o intelegere mai buna a modului de utilizare al unui Arduino, in special functiile sale principale. De asemenea, in implementarea proiectului este folositor pentru ​ a observa si studia modul in care s-a efectuat lucrul cu datele provenite de la mai multe butoane.
 ===== Download ===== ===== Download =====
  
-<note warning>​ +* {{ :pm:​prj2022:​arosca:​arhivaplusreadme_sarugabriel333cb.zip | Arhiva cod sursa + comentarii + README ​}} 
-O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectuluisurse, scheme, etcUn fişier ​README, un ChangeLog, un script ​de compilare şi copiere automată pe uC crează întotdeauna ​impresie bună ;-).+ 
 +In aceasta sectiune ​de DOWNLOAD putem gasi arhiva care contine urmatoarele:​ 
 + 
 +  * Codul sursa al proiectului;​ 
 +  * README, pentru ​explicare mai succinta a functiilor din proiect; 
 +  * Libraria accelerometrului;
  
-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**. 
-</​note>​ 
  
 ==== Jurnal ====  ==== Jurnal ==== 
  
  
-Puteți avea și o secțiune de jurnal ​în care să poată urmări ​asistentul de proiect ​progresul proiectului.+Ca o secțiune de jurnal, in care laborantul ​să poată urmări progresul proiectului.
  
   - **Alegere Tema Proiect** ​              - **12.04.2022**   - **Alegere Tema Proiect** ​              - **12.04.2022**
pm/prj2022/arosca/snakegamewithgyroscope.1653326756.txt.gz · Last modified: 2022/05/23 20:25 by gabriel.saru
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