
// Ces variables représentent les dimensions du terrain (et du bord du terrain) en nombre de pixels. Elles doivent être cohérentes avec la taille de la fenêtre graphique
int bordsDuTerrain = 200;
int largeurDuTerrain = 600;

// Cette variable devra être vraie lorsque le joueur actif est en train de tirer.
boolean en_train_de_viser = false;
// Cette variable devra être vraie lorsque le tir est parti et que le boulet est toujours dans les airs.
boolean tir_en_cours = false;

// Cette variable contiendra la direction du tir du joueur lorsque celui ci prépare son tir (i.e. lorsque le bouton de la souris est maintenu enfoncé)
float directionX, directionY;


// Cette variable représentera le joueur dont c'est le tour (1 pour joueur 1 et 2 pour joueur 2)
int joueur_courant = 1;

// Ces deux variables contiendront la position du boulet dans la fenêtre graphique
float pos_boulet_x, pos_boulet_y;
// Ces deux variables contiendront la vitesse du boulet dans la fenêtre graphique (elles sont exprimées en nombre de pixel)
float vitesse_boulet_x, vitesse_boulet_y;

// Cette variable contient la gravité dans notre univers de jeu.
float gravite = 0.098; 

// Cette variable contient la vitesse maximale des tirs des joueurs. Attention, une valeur trop élevée peut engendrer des erreurs de calcul.
float vitesse_max_de_tir = 10.0 / 100.0;

// Ces variables sont les points de vie des deux joeurs.
int PVJoueur1, PVJoueur2;

boolean cestLaFin;



/*********************************** LES FONCTIONS PROCESSING ***************************************
 *****************************************************************************************************/

void setup()
{
  size(1000, 600, P3D);
  initialiser();
  PVJoueur1 = 2;
  PVJoueur2 = 2;
  cestLaFin = false;

  dessinerTout();
}

void draw()
{
  if (!fini())
  {
    if (tir_en_cours && !en_train_de_viser)
    {
      dessinerTout();
      dessinerBoulet(pos_boulet_x, pos_boulet_y);
    }
    if (tir_en_cours && besoinDeMiseAJourDuBoulet())
    {
      avancerBoulet();
      dessinerTout();
      dessinerBoulet(pos_boulet_x, pos_boulet_y);
      if (testerCollisionAvecJoueur(pos_boulet_x, pos_boulet_y, autreJoueur(joueur_courant)))
      {
        println("touché");
        reduirePointDeVie(autreJoueur(joueur_courant));
        nouveauTour();
      } else if (collisionAvecSol(pos_boulet_x, pos_boulet_y) && tir_en_cours) // j'enleve le !
      {  
        println("collision avec le terrain");
        creuserTerrain(pos_boulet_x, pos_boulet_y);

        nouveauTour();
      } else if (bouletEstSorti(pos_boulet_x, pos_boulet_y))
      {
        println("Sorti"); 
        nouveauTour();
      }
    }
  } else
  {
    if (cestLaFin == false)
    {
      println("Fini");
      cestLaFin = true;
    }
  }
}

// Cete fonction Processing est appelée directement par processing lorsque le joueur presse un bouton la souris.
void mousePressed()
{
  if (!tir_en_cours && !fini())
    en_train_de_viser = true;
}
// Cete fonction Processing est appelée directement par processing lorsque le joueur bouge la souris lorsq'un bouton de la souris est enfoncé. Elle nous servira a afficher la direction du tir du joueur courant
void mouseDragged()
{
  if (en_train_de_viser)
  {
    dessinerTout();
    calculerDirectionDeTir(joueur_courant, mouseX, mouseY);
    dessinerDirectionDeTir(joueur_courant);
    aideALaVisee();
  }
}

// Cete fonction Processing est appelée directement par processing lorsque le joueur relache un bouton de la souris

void mouseReleased()
{
  if (en_train_de_viser)
  {
    en_train_de_viser = false;
    tir_en_cours = true;
    pos_boulet_x = positionXDuJoueur(joueur_courant);
    pos_boulet_y = positionYDuJoueur(joueur_courant);
    temps_derniere_mise_a_jour = millis();

    vitesse_boulet_x = directionX*vitesse_max_de_tir  ;
    vitesse_boulet_y = directionY*vitesse_max_de_tir  ;
  }
}
void mouseClicked()
{
  println("La souris a été cliquée");
}



/*********************************** LES FONCTIONS DU NECESSAIRES AU JEU ***************************************
 *****************************************************************************************************/


// Cette fonction doit réduire de 1 le nombre de point de vie du joueur passé en paramètre
void reduirePointDeVie(int joueur)
{
  if (joueur == 1)
  {
    PVJoueur1--; // PVJoueur1 = PVJoueur1 - 1;
    println("Il vous reste "+PVJoueur1+" vies");
  } else
  {
    PVJoueur2--;
    println("Il vous reste "+PVJoueur2+" vies");
  }
}

// Cette fonction doit renvoyer vrai lorsque le jeu est fini
boolean fini()
{
  if (PVJoueur1 == 0 || PVJoueur2 == 0)
  {
    return true;
  }
  return(false);
}

// Cette fonction commence un nouvea tour. Elle doit changer le joueur courant et remettre à 0 ou false les variables nécessaires.
void nouveauTour()
{
  tir_en_cours = false;
  joueur_courant = autreJoueur(joueur_courant);
  dessinerTout();
}
// Cette fonction dessine le plateau de jeu (sauf le boulet)
void dessinerTout()
{
  background(255, 255, 255);
  dessinerCiel();
  dessinerTerrain();
  dessinerJoueur(1);
  dessinerJoueur(2);
  afficherVieDuJoueur(1);
  afficherVieDuJoueur(2);
  afficheLeTourDuJoueur(joueur_courant);
}

// Cette fonction doit renvoyer le numéro du joueur adverse au joueur passé en paramètre (elle doit renvoyée 1 si le paramètre est 2 et inversement).
int autreJoueur(int joueur)
{
  if (joueur == 1)
  {
    return 2;
  } else
  {
    return 1;
  }
}
// Cette fonction est responsable pour le déplacement du boulet. Elle doit mettre à jour la position x et y du boulet et modifier la vitesse en fonction des divers paramètres.
void avancerBoulet()
{

  pos_boulet_x += vitesse_boulet_x;
  vitesse_boulet_y += gravite;
  pos_boulet_y += vitesse_boulet_y;
  temps_derniere_mise_a_jour = millis();
}

void aideALaVisee()
{
  float pos_x, pos_y, vitesse_x, vitesse_y;
  pos_x = positionXDuJoueur(joueur_courant);
  pos_y = positionYDuJoueur(joueur_courant);

  vitesse_x = directionX*vitesse_max_de_tir  ;
  vitesse_y = directionY*vitesse_max_de_tir  ;
  for(int i=1;i<=200;i++)
  {
    ellipse(pos_x,pos_y,2,2);
    pos_x += vitesse_x;
    vitesse_y += gravite;
    pos_y += vitesse_y;
  }
}

// Cette fonction renvoie vrai si le temps (en milliseconde) écoulé entre la dernière mise a jour de la position du boulet et maintenant est trop long (ici, si il est supérieur a 10 ms)
boolean besoinDeMiseAJourDuBoulet()
{
  return millis() - temps_derniere_mise_a_jour > 10;
}

// Cette fonction renvoie vrai si les coordonnées x et y passées en paramètre sont à une distance de 40 unités ou moins de la position du joueur j passé en paramètre. Cette fonction servira a tester si le boulet est entré en collision avec le chateau du joueur j
boolean testerCollisionAvecJoueur(float x, float y, int j)
{
  if (dist(x, y, positionXDuJoueur(j), positionYDuJoueur(j))<=40)
    return true;

  return (false);
}
// Cette fonction renvoie vrai si les coordonnées x et y (en paramètre) sont en dehors du plateau de jeu (x ou y sortis de la fenetre de jeu (excepté pour la sortie par le haut eventuellement)
boolean bouletEstSorti(float x, float y)
{
  if ((x>=0)&&(x<=1000)&&(y<=600))
  {
    return(false);
  }
  return true;
}

/* Cette fonction calcule la direction normée du tir du joueur en fonction de la position de la souris (paramètres x et y) et de la position du joueur (passé en paramètre). 
 De façon simple, cette fonction remplit les variables directionX et directionY qui représenteront la direction du tir. Il est a noter que cette direction aura une longueur maximale de 100 unités.
 */

void calculerDirectionDeTir(int joueur, float x, float y)
{

  directionX = x - positionXDuJoueur(joueur);
  directionY = y - positionYDuJoueur(joueur);

  directionX *= 0.3;
  directionY *= 0.3;

  float norme = dist(directionX, directionY, 0, 0);

  norme = 100.0 / max(norme, 100.0);

  directionX *= norme;
  directionY *= norme;
}
