This is an old revision of the document!


Super Mario Jumping Game

Introducere

Scopul acestui proiect este să ofere utilizatorilor un joc Super Mario, care poate fi jucat în timpul liber. Proiectul a fost creat pentru a fi ușor de jucat și de înțeles, fiind util și pentru învățarea conceptelor hardware și software.

Descriere generală

Schemă bloc:

Hardware Design

Lista de piese:

  • Arduino UNO
  • Ecran LCD Albastru 2004
  • Breadbord 400
  • Componente de baza (cablu USB, pini, fire)
  • Buzzer activ
  • Joystick
  • LED
  • Rezistente

Software Design

Descrierea codului aplicaţiei (firmware):

  • Visual Studio Code / Arduino
  • LiquidCrystal_I2C
  • Wire
  • draw.io
  • Tinkercad

int gameOver[] = { NOTE_C5,-4, NOTE_G4,-4, NOTE_E4,4, NOTE_A4,-8, NOTE_B4,-8, NOTE_A4,-8, NOTE_GS4,-8, NOTE_AS4,-8, NOTE_GS4,-8, NOTE_G4,8, NOTE_D4,8, NOTE_E4,-2, };

void graphics(){

 byte man[64] = {
 // position 1
  B01100,
  B01100,
  B00000,
  B01110,
  B11100,
  B01100,
  B11010, 
  B10011,
  // position 2
  B01100,
  B01100,
  B00000,
  B01100,
  B01100,
  B01100,
  B01100,
  B01110,
  // Jump
  B01100,
  B01100,
  B00000,
  B11110,
  B01101,
  B11111,
  B10000,
  B00000,
  // Jump lower
  B11110,
  B01101,
  B11111,
  B10000,
  B00000,
  B00000,
  B00000,
  B00000,
  // Ground
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  // Ground right
  B00011,
  B00011,
  B00011,
  B00011,
  B00011,
  B00011,
  B00011,
  B00011,
  // Ground left
  B11000,
  B11000,
  B11000,
  B11000,
  B11000,
  B11000,
  B11000,
  B11000
 };
 int g;
 for (g = 0; g < 8; g++) {
     lcd.createChar(g, &man[g*8]);
 }

}

void startGame(){

 lcd.setCursor (1,1);
 lcd.print("Press Up to Start!");
 lcd.setCursor (0,1);
 currentPos = run_1;

}

void drawmanWalk(){

 man_low_pos=1;
 lcd.setCursor(0,1);
 currentPos = run_2;
 lcd.write(byte(currentPos));
 delay(120);
 lcd.setCursor(0,1);
 currentPos = run_1;
 lcd.write(byte(currentPos));
 delay(120);
 detect();

}

void drawmanJump(){

  man_low_pos=1;
  man_up_pos=1;
  lcd.setCursor (0,0);
  currentPosUp = jump_half_head;
  lcd.write(byte(currentPosUp));
  lcd.setCursor (0,1);
  currentPosDown = jump_half_body;
  lcd.write(byte(currentPosDown));
  detect();
  tone(buzzer, NOTE_A6, 100);
  delay(110);
  drawObject();
  man_low_pos=0;
  man_up_pos=1;
  lcd.setCursor (0,0);
  currentPosUp = jump_high;
  lcd.write(byte(currentPosUp));
  lcd.setCursor (0,1);
  lcd.print(" ");
  detect();
  
  delay(110);
  drawObject();
  detect();
  delay(140);
  drawObject();
  detect();
  man_low_pos=1;
  man_up_pos=1;
  lcd.setCursor (0,0);
  currentPosUp = jump_half_head;
  lcd.write(byte(currentPosUp));
  lcd.setCursor (0,1);
  currentPosDown = jump_half_body;
  lcd.write(byte(currentPosDown));
  delay(140);
  lcd.setCursor(0,0);
  lcd.print(" ");
  man_up_pos=0;
  man_low_pos=1;
  detect();

}

void objectRandom (int upperBG[], int lowerBG[]){

int ObjectPos = random(5,10);

switch (ObjectPos){

     case upperObject1:
         lowerBG[16] = empty;
         if (lowerBG[15] == lowerObject1) 
             upperBG[16] = empty;
         else 
             upperBG[16] = upperObject1;    
         break;
     case lowerObject1:
         if ((lowerBG[15] == lowerObject1)||
             (lowerBG[14] == lowerObject1)|| 
             (lowerBG[13] == lowerObject1)||
             (upperBG[15] == upperObject1)){
             lowerBG[16] = empty;
         }
         else 
             lowerBG[16] = lowerObject1;
         break;
     case empty:
     case 8:
     case 9:
     case 10:
         upperBG[16] = empty;
         lowerBG[16] = empty;
         break;
 }

}

void detect(){

 if((man_up_pos==1 && upperBG[0]!=7)||
     (man_low_pos==1&&lowerBG[0]!=7)){
     lcd.clear();
     lcd.setCursor(1,0);
     playing = false;
     scoring = false;
 }

}

void drawObject (){

if(millis() - ts > 300) {
  ts = millis();
  objectRandom(upperBG,lowerBG);
}
 for (int i = 0; i < 16; i++){
     upperBG[i]=upperBG[i+1];
     lowerBG[i]=lowerBG[i+1];
 }
 if(upperBG[0]!=7){
     lcd.setCursor(0,0);
     lcd.write(byte(upperBG[0]));
 }
 else if(man_up_pos==0){
     lcd.setCursor(0,0);
     lcd.print(" ");
 }
 if(lowerBG[0]!=7){
     lcd.setCursor(0,1);
     lcd.write(byte(lowerBG[0]));
 }
 else if(man_low_pos==0){
     lcd.setCursor(0,1);
     lcd.print(" ");
 }
 for (int i = 1; i < 16; i++){
     lcd.setCursor(i,0);
     lcd.write(byte(upperBG[i]));
     
     lcd.setCursor(i,1);
     lcd.write(byte(lowerBG[i]));
 }

}

void over(){

digitalWrite(RED_LED, HIGH);
int wholenote = (60000 * 4) / 200;
int noteDuration = 0;
for(int i = 0; i < 24; i+=2){
  int divider = gameOver[i + 1];
  if (divider > 0) {
      noteDuration = (wholenote) / divider;
  } else if (divider < 0) {
      noteDuration = (wholenote) / abs(divider);
      noteDuration *= 1.5; 
  }
  tone(buzzer, gameOver[i], noteDuration * 0.9);
  delay(noteDuration);
  noTone(buzzer);
}
 lcd.clear();
 lcd.setCursor (5,1);
 lcd.print ("Game Over!");
 lcd.setCursor (3,2);
 lcd.print ("Your Score:");
 lcd.setCursor (14,2);
 lcd.print (score);
 delay(delay_time);
 game_over = true;
 

}

void setup() {

  Serial.begin(9600);
  pinMode(jump_button, INPUT);
  digitalWrite(jump_button, HIGH);
  graphics();
  lcd.begin(20, 4);
  lcd.backlight();
  pinMode(buzzerPin, OUTPUT);
  pinMode(RED_LED, OUTPUT);
  digitalWrite(RED_LED, LOW);

}

void loop() {

 while(game_over) { 
   buttonPushed = (digitalRead(jump_button) == LOW);
   if(buttonPushed) {
    lcd.clear();
    buttonPushed = false;
    playing = false;
    scoring = false;
    score = 0;
    for(int i = 0; i < 17; i++) { 
      upperBG[i]= empty;
      lowerBG[i] = empty;
    }
    game_over = false;
   }
 }
 
  buttonPushed = (digitalRead(jump_button) == LOW);
  
 if (!playing && score == 0) {
      startGame();
      digitalWrite(RED_LED, LOW);
      if (buttonPushed) {
          graphics();
          playing = true;
          scoring = true;
          buttonPushed = false;
          lcd.clear();
      }
 }
  if(!playing && score > 0) {
      over();
      
  }
 
 if (playing){
     drawObject();
     drawmanWalk();
      if((mode == 0 || mode == 1 ) && buttonPushed){
         drawmanJump();
         buttonPushed = false;
      }
      if(mode == 1) {
           if (lowerBG[3] == lowerObject1){
               digitalWrite(RED_LED, HIGH);
           } else {
               digitalWrite(RED_LED, LOW);
           }
       }
      if(mode == 2) {
          if (man_low_pos==1 && lowerBG[2]!=7){
              drawmanJump();
          } 
      }
  }

if (scoring == true){

      score++;
  }

}

Rezultate Obţinute

Concluzii

Proiectul m-a ajutat să aprofundez conceptele studiate la laboratoarele de PM, mai ales să înțeleg utilizarea protocolului I2C.

Download

Arhiva care contine codul sursa : supermario.zip

Export to PDF

Bibliografie/Resurse

pm/prj2023/ncaroi/supermariogame.1685402444.txt.gz · Last modified: 2023/05/30 02:20 by elena_ioana.stefan
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