Pong with nucleo en shield

Dependencies:   C12832 LM75B MMA7660 Speaker mbed

Fork of app-shield-LCD by Chris Styles

main.cpp

Committer:
kv09
Date:
2017-01-24
Revision:
6:402e96a482a9
Parent:
4:39c7c31b8fb0

File content as of revision 6:402e96a482a9:

#include "mbed.h"
#include "C12832.h"
#include "MMA7660.h"
#include "LM75B.h"
#include "Speaker.h"
#include <stdlib.h>
#include <time.h>
#include <string>

  // Using Arduino pin notation
  /************* LCD ****************/
  C12832 lcd(D11, D13, D12, D7, D10);

/********* Potentiometre *********/
AnalogIn pot1(A0);
AnalogIn pot2(A1);

/************** LED ***************/
DigitalOut r(D5);
DigitalOut b(D8);
DigitalOut g(D9);

/*********** Analogue *************/
DigitalIn up(A2); //AnalogIn
DigitalIn down(A3);
DigitalIn gau(A4);
DigitalIn droi(A5);
DigitalIn fire(D4);

/*********** Speaker **************/
Speaker spkr(D6);

/********* Accelerometre **********/
MMA7660 MMA(D14, D15);

/***** Capteur de température *****/
LM75B sensor(D14, D15);

//Variable globale
// Integer
int horizontalBall = 35;
int scorej1 = 0;
int scorej2 = 0;
int verticalJ1 = 0;
int verticalJ2 = 0;
int victoirej1 = 0;
int victoirej2 = 0;
int nbcontact = 0;
int rapide = 3;
int choix;
int ajoutvit = 1;
// Float
float angle = 1.5;
float verticalBall = 5.0;
float vitesse = 0;
float vitessebase = 0;
// Boolean
bool avance = true;
bool recule = false;
bool but = false;
bool joue = true;
bool diag1 = true;
bool diag2 = false;
bool partie = true;
bool lance = true;
bool stop = false;
//String
string tab[3] = {
  "lent",
  "normal",
  "rapide"
};;

// Fonction du contact entre la balle et le joueur
bool contact(int a, float b) {
  nbcontact++;
  // Fait accelerer la balle pour un certain nombre de contact
  if (nbcontact % rapide == 0) {
    if (vitesse > 0.03) {
      vitesse = vitesse - 0.005;
    }
    if (ajoutvit < 4) {
      ajoutvit++;
    }
  }
  // Variation de l'angle en fonction d'ou est tapé la balle
  if (a >= b + 2 && a <= b + 5) {
    angle = 0.5;
    return true;
  } else if (a >= b - 1 && a <= b + 2) {
    angle = 1.0;
    return true;
  } else if (a >= b - 4 && a <= b - 1) {
    angle = 1.5;
    return true;
  } else {
    return false;
  }
}

// Fonction d'initialisationialisation
void initialisation() {
  horizontalBall = 50;
  verticalBall = (rand() % 20) + 1;
  avance = true;
  recule = false;
  but = false;
  joue = true;
  vitesse = vitessebase;
  ajoutvit = 1;
  lcd.cls();
  // Décompte avant commencement de la partie
  for (int i = 2; i > 0; i--) {
    lcd.locate(35, 10);
    lcd.printf("Commence dans %d", i);
    wait(1);
    lcd.cls();
  }
}

// Fonction d'affichage
void affichage() {
  // Cadre du terrain
  lcd.rect(32, 0, 127, 31, 1);
  lcd.copy_to_lcd();

  //Score
  lcd.locate(0, 0);
  lcd.printf("SCORE");
  lcd.locate(2, 12);
  lcd.printf("J1");
  lcd.locate(3, 20);
  lcd.printf("%d", scorej1);
  lcd.locate(15, 12);
  lcd.printf("J2");
  lcd.locate(16, 20);
  lcd.printf("%d", scorej2);

  //bar 1
  verticalJ1 = (float) pot1 * 22;
  lcd.locate(35, verticalJ1);
  lcd.printf("l");

  // bar 2
  verticalJ2 = (float) pot2 * 22;
  lcd.locate(120, verticalJ2);
  lcd.printf("l");

  //balle
  lcd.locate(horizontalBall, verticalBall);
  lcd.printf("o");
}

// Fonction de son pour le démarrage
void son(float f) {
  spkr.PlayNote(969.0 * f, 0.1, 1.1);
  spkr.PlayNote(800.0 * f, 0.1, 1.1);
  spkr.PlayNote(768.0 * f, 0.1, 1.1);
  spkr.PlayNote(879.0 * f, 0.1, 1.1);
}

// Fonction de son pour un but
void son_marque() {
  spkr.PlayNote(1200.0, 0.1, 1.1);
  spkr.PlayNote(900.0, 0.1, 1.1);
  spkr.PlayNote(1000.0, 0.1, 1.1);
  spkr.PlayNote(700.0, 0.1, 1.1);
}

// Fonction de son pour une victoire
void son_victoire() {
  spkr.PlayNote(1800.0, 0.2, 0.8);
  wait(0.03);
  spkr.PlayNote(1800.0, 0.2, 0.8);
  wait(0.03);
  spkr.PlayNote(1800.0, 0.5, 0.8);
  wait(0.03);
  spkr.PlayNote(600.0, 0.7, 1.1);
  wait(0.03);
  spkr.PlayNote(1800.0, 0.2, 0.8);
  wait(0.03);
  spkr.PlayNote(1600.0, 0.2, 0.8);
  wait(0.03);
  spkr.PlayNote(1800.0, 0.2, 0.8);
  wait(0.03);
  spkr.PlayNote(1800.0, 0.5, 0.8);
  wait(0.03);
  spkr.PlayNote(600.0, 0.7, 1.1);
}

// Fonction de son lors d'un contact avec
void son_contact() {
  spkr.PlayNote(900.0, 0.1, 1.1);
}

// Fonction pour le mouvement de la balle
void mouvement_balle(bool av, bool rec) {
  // Fonction pour faire avancer ou reculer la balle
  if (av) {
    horizontalBall = horizontalBall + ajoutvit;
  }
  if (rec) {
    horizontalBall = horizontalBall - ajoutvit;
  }
  // Fonction pour le rebond de la balle sur le haut et le bas de l'écran
  if (diag1) {
    verticalBall = verticalBall + angle;
  }
  if (diag2) {
    verticalBall = verticalBall - angle;
  }
  if (verticalBall < 0) {
    diag1 = true;
    diag2 = false;
  }
  if (verticalBall > 22) {
    diag1 = false;
    diag2 = true;
  }
}

// Fonction pour le but
void marque() {
  // Si c'est le joueur qui marque
  if (horizontalBall >= 115) {
    // Si il y a contact la balle repart
    if (contact(verticalJ2, verticalBall)) {
      son_contact();
      avance = false;
      recule = true;
    }
    // Sinon il y a but
    else {
      but = true;
      scorej1++;
      son_marque();
      joue = false;
      r = 0;
      b = 1;
      g = 1;
      wait(0.2);
      r = 1;
      b = 1;
      g = 1;
    }
  }
  // Si c'est le joueur 2 qui marque
  if (horizontalBall <= 35) {
    // Si il y a contact la balle repart
    if (contact(verticalJ1, verticalBall)) {
      son_contact();
      avance = true;
      recule = false;
    }
    // Sinon il y a but
    else {
      but = true;
      scorej2++;
      son_marque();
      joue = false;
      r = 1;
      b = 0;
      g = 1;
      wait(0.2);
      r = 1;
      b = 1;
      g = 1;
    }
  }
}

// Fonction de lancement du jeux
void commencement() {
  lcd.rect(0, 0, 127, 31, 1);
  lcd.copy_to_lcd();
  scorej1 = 0;
  scorej2 = 0;
  // Menu pour le choixx de la vitesse
  while (!fire) {
    lcd.locate(25, 10);
    lcd.printf("choixsissez la vitesse");
    lcd.locate(50, 18);
    lcd.printf("- %s", tab[choix]);
    // Monte dans le menu
    if (!up) {
      choix++;
      if (choix > 2) {
        choix = 0;
      }
    }
    // Descend dans le menu
    if (!down) {
      choix--;
      if (choix < 0) {
        choix = 2;
      }
    }
    wait(0.2);
    lcd.cls();
  }
  // Liste des choixx de vitesse
  switch (choix) {
  case 0:
    vitessebase = 0.09;
    rapide = 5;
    break;
  case 1:
    vitessebase = 0.07;
    rapide = 3;
    break;
  case 2:
    vitessebase = 0.05;
    rapide = 2;
    ajoutvit = 2;
    break;
  default:
    vitessebase = 0.09;
    rapide = 5;
  }
  partie = true;
  lance = false;
}

// Fonction pour savoir qui gagne
void victoire() {
  /* Si le score arrive à 5
   * On ajoute une victoire pour le joueur qui gagne
   * Appel de la fonction de musique de victoire
   */
  if (scorej1 == 5) {
    lcd.cls();
    lcd.locate(25, 10);
    lcd.printf("Victoire du joueur 1");
    son_victoire();
    victoirej1++;
    wait(2);
    partie = false;
  }
  if (scorej2 == 5) {
    lcd.cls();
    lcd.locate(25, 10);
    lcd.printf("Victoire du joueur 2");
    son_victoire();
    victoirej2++;
    wait(2);
    partie = false;
  }
}

// Fonction qui permet de faire rejouer lorsque l'on secoue le nucleo
void rejouer() {
  float AX = 0, AY = 0, AZ = 0;
  float valeur = 1.3;
  int compteur = 0;
  int sortie = 0;
  lcd.cls();
  lcd.locate(20, 8);
  lcd.printf("Secouer pour rejouer");
  // Si le joueur secoue la nucleo on rejoue
  while (compteur < 3) {
    // Test si les capteurs dépasse la valeur donné si oui on ajoute 1 au compteur
    if (MMA.x() > AX + valeur || MMA.y() > AY + valeur || MMA.z() > AZ + valeur) {
      compteur++;
    }
    wait(0.2);
    sortie++;
    // Sinon on attend 5 seconde pour sortir
    if (sortie == 25) {
      compteur = 25;
    }
  }
  if (compteur == 25) {
    lance = false;
  } else {
    lance = true;
  }
}

// Fonction pour afficher le récapitulatif des victoires
void recapitulatif() {
  // Affiche le nombre de victoire de chaque joueur
  lcd.cls();
  lcd.locate(25, 10);
  lcd.printf("Joueur 1 : %d victoires", victoirej1);
  lcd.locate(25, 20);
  lcd.printf("Joueur 2 : %d victoires", victoirej2);
  wait(4);
  lcd.cls();
  lcd.locate(30, 10);
  lcd.printf("Merci d avoir joue");
  wait(2);
}

// Fonction pour faire pause lors du jeux
void pause() {
  // Si il appuie sur le bouton du joystick on lance la pause
  if (fire) {
    stop = true;
    lcd.cls();
    lcd.locate(50, 10);
    lcd.printf("Pause");
    lcd.locate(25, 2);
    // Affiche la température récupéré par le capteur
    lcd.printf("Temperature = %.1f\n", sensor.read());
    lcd.locate(3, 18);
    // Affiche le score
    lcd.printf("joueur 1 : %d - joueur 2 : %d", scorej1, scorej2);
    int lightp = 6;
    while (stop) {
      // On fait clignoter la LED en vert
      if (lightp % 6 == 0) {
        r = 1;
        b = 1;
        g = 0;
      }
      wait(0.1);
      // Si il réappuie sur le bouton du joystick on sort de la pause
      if (fire) {
        stop = false;
      }
      // On éteint la lED
      r = 1;
      g = 1;
      b = 1;
      lightp++;
    }
    lcd.cls();
    affichage();
    wait(0.8);
  }
}

// Fonction de démarrage du jeu
void lancement() {
  r = 1;
  g = 1;
  b = 1;
  lcd.cls();
  lcd.locate(50, 10);
  lcd.printf("Bienvenue");
  wait(1);

  lcd.cls();
  int po = 45, ng = 17;
  bool ok = true;
  int light = 3;
  float zz = 1.0;
  while (ok) {
    son(zz);
    lcd.cls();
    lcd.locate(15, 17);
    lcd.printf("l");
    lcd.locate(110, 6);
    lcd.printf("l");
    // Affiche le nom PoNG en le déplacent
    lcd.locate(po, ng);
    lcd.printf("PoNG");
    po = po + 4;
    ng--;
    if (po == 85 || ng == 0) {
      ok = false;
    }
    // Fait clignoter la LED en Rouge, Bleu et Vert
    if (light % 3 == 0) {
      r = 1;
      g = 1;
      b = 0;
    }
    if (light % 3 == 1) {
      r = 1;
      g = 0;
      b = 1;
    }
    if (light % 3 == 2) {
      r = 0;
      g = 1;
      b = 1;
    }
    wait(0.08);
    r = 1;
    g = 1;
    b = 1;
    light++;
    // Diminue l'intensité de la musique
    zz = zz - 0.05;
  }
}

// Fonction de fin
void fin() {
  lcd.cls();
  int des = 9;
  r = 1;
  b = 1;
  g = 1;
  while (des - 8 < 19) {
    // Affiche le générique
    lcd.locate(25, des - 4);
    lcd.printf("Realise par Mael");
    // Musique de fin
    switch (des % 9) {
    case 0:
      spkr.PlayNote(220.00, 0.5, 0.8);
      r = 0;
      b = 1;
      g = 1;
      wait(0.250);
      break;
    case 1:
      spkr.PlayNote(220.00, 0.5, 0.8);
      r = 1;
      b = 1;
      g = 1;
      wait(0.250);
      break;
    case 2:
      spkr.PlayNote(220.00, 0.5, 0.8);
      r = 0;
      b = 1;
      g = 1;
      wait(0.250);
      break;
    case 3:
      spkr.PlayNote(174.61, 0.375, 0.8);
      r = 1;
      b = 1;
      g = 1;
      wait(0.187);
      break;
    case 4:
      spkr.PlayNote(261.63, 0.125, 0.8);
      r = 0;
      b = 1;
      g = 1;
      wait(0.062);
      break;
    case 5:
      spkr.PlayNote(220.00, 0.5, 0.8);
      r = 1;
      b = 1;
      g = 1;
      wait(0.250);
      break;
    case 6:
      spkr.PlayNote(174.61, 0.375, 0.8);
      r = 0;
      b = 1;
      g = 1;
      wait(0.187);
      break;
    case 7:
      spkr.PlayNote(261.63, 0.125, 0.8);
      r = 1;
      b = 1;
      g = 1;
      wait(0.062);
      break;
    case 8:
      spkr.PlayNote(220.00, 0.7, 0.8);
      r = 0;
      b = 1;
      g = 1;
      wait(0.7);
      break;
    default:
      r = 1;
      b = 1;
      g = 1;
    }
    des++;
  }
  lcd.cls();
  r = 1;
  b = 1;
  g = 1;
}

// Fonction pour effacer une zone sur l'écran
void efface() {
  //bar 1
  lcd.locate(35, verticalJ1);
  lcd.printf(" ");

  // bar 2
  lcd.locate(120, verticalJ2);
  lcd.printf(" ");

  //balle
  lcd.locate(horizontalBall - 3, verticalBall);
  lcd.printf("    ");
  lcd.locate(horizontalBall - 3, verticalBall - 1);
  lcd.printf("    ");
  lcd.locate(horizontalBall - 3, verticalBall + 1);
  lcd.printf("    ");
}

// Fonction de main
int main() {
  lancement();
  // Boucle pour jouer un match
  while (lance) {
    commencement();
    // Boucle pour jouer une partie
    while (partie) {
      initialisation();
      // Boucle pour jouer une manche
      while (joue) {
        affichage();

        marque();

        pause();

        mouvement_balle(avance, recule);

        victoire();

        wait(vitesse);

        efface();
      }
      wait(1);
    }
    rejouer();
  }
  recapitulatif();
  fin();
}