Cliquer ici pour revenir au début du tutoriel.

Maintenant que nous pouvons afficher les graphismes du jeu, nous allons y ajouter des contrôles afin de pouvoir déplacer le joueur.

On peut retirer les commentaires de la ligne surveilleTouches()  et créer la fonction:

...
void loop() {
  afficheGraphismes();
  // joueBruitages();
  surveilleTouches();
  // logiqueJeu();
 }

 

Nous allons écrire le test pour le déplacement vers le haut. On lancera la demande de déplacement si le joueur a appuyé sur la touche haut.

...
 initialiserKitco(1);
 
}

void surveilleTouches() {
  if (toucheHaut()) {
    deplace(HAUT);
  }
}

// Loop est la boucle principale, va se lancer en boucle après Setup
void loop() {
...

Cependant cela ne suffit pas. Il faut attendre que le joueur ait relaché la touche pour lancer la commande une deuxième fois. Sinon le joueur va se déplacer trop vite. On va donc utiliser une variable « relacheTouche » pour ne lancer la commande que lorsque le joueur a bien relaché la touche.

...
 initialiserKitco(1);
}

//
// LES CONTROLES
//
int relacheTouche = 0;

// racourci case suivante:
#define SUIVANTE(DIR,NB) niveau[ls(DIR,NB)][cs(DIR,NB)]

// la position initiale du joueur (dépend du niveau)
int ligneJoueur = 1;
int colonneJoueur = 1;
#define HAUT   1
#define BAS    2
#define DROITE 3
#define GAUCHE 4 

void surveilleTouches() {
  if (toucheHaut()) {
  if (toucheHaut() && relacheTouche) {
    deplace(HAUT);
  }
  if (toucheBas() && relacheTouche) {
    deplace(BAS);
  }
  if (toucheDroite() && relacheTouche) {
    deplace(DROITE);
  }
  if (toucheGauche() && relacheTouche) {
    deplace(GAUCHE);
  }
  if (touche()) {
    relacheTouche = 0;
  } else {
    relacheTouche = 1;
  }
}

// Loop est la boucle principale, va se lancer en boucle après Setup
void loop() {
...

Maintenant il faut compléter la fonction deplace(). Quand doit-on refuser le déplacement? Il y a trois cas:

  1. si la case suivant le joueur est un mur
  2. s’il y a au moins deux caisses à la suite du joueur
  3. S’il y a une caisse et un mur à la suite du joueur
...
#define BAS 2
#define DROITE 3
#define GAUCHE 4 

void deplace(int dir) {

  // si la case suivant le joueur est un mur
  if (SUIVANTE(dir,1) == 'M') {
    // on ne déplace pas le joueur
    return;
  }

  // s'il y a au moins deux caisses à la suite du joueur
  if ( (SUIVANTE(dir,1) == '$' || SUIVANTE(dir,1) == '*') &&
       (SUIVANTE(dir,2) == '$' || SUIVANTE(dir,2) == '*')){
   // on ne déplace pas le joueur
   return;
  }

  // S'il y a une caisse et un mur à la suite du joueur
  if ( (SUIVANTE(dir,1) == '$' || SUIVANTE(dir,1) == '*') &&
       (SUIVANTE(dir,2) == 'M')) {
    // on ne déplace pas le joueur
    return;
  }

  // à ce point du programme, on sait que le déplacement est autorisé  
}

void surveilleTouches() {
 if (toucheHaut() && relacheTouche) {
...

Quand le déplacement est autorisé, il faut maintenant déplacer le joueur et l’éventuel caisse qui est au dessus de lui:

...
  }

 // à ce point du programme, on sait que le déplacement est autorisé 

// Si la case suivante contient une caisse
if (SUIVANTE(dir,1) == '$' || SUIVANTE(dir,1) == '*') {
  // on déplace la caisse à la nouvelle case
  if (SUIVANTE(dir,2) == '.') {
    SUIVANTE(dir,2) = '*'; } else {
    SUIVANTE(dir,2) = '$';
  }
  // on retire la caisse de la case précédente
  if (SUIVANTE(dir,1) == '$') {
    SUIVANTE(dir,1) = ' '; } else {
    SUIVANTE(dir,1) = '.';
  }
}

// On positionne le joueur à la case suivante
if (SUIVANTE(dir,1) == '.') {
 SUIVANTE(dir,1) = '+'; } else {
 SUIVANTE(dir,1) = '@'; 
}

// Et on le retire de la case précédente
if (niveau[ligneJoueur][colonneJoueur] == '+') {
  niveau[ligneJoueur][colonneJoueur] = '.'; } else {
  niveau[ligneJoueur][colonneJoueur] = ' '; 
}

// on met aussi à jour les coordonnées du joueurs à la case suivante
ligneJoueur = ls(dir,1);
colonneJoueur = cs(dir,1);

}

void surveilleTouches() {
 if (toucheHaut() && relacheTouche) {
...

N’oublions pas de faire les fonctions ls et cs (lignesuivante et colonnesuivante), ainsi que le define pour SUIVANTE(DIR,NB) (qui a permit de rendre le code beaucoup plus lisible).

:

...
#define BAS 2
#define DROITE 3
#define GAUCHE 4 

// fonction ligneSuivante
int ls(int direction, int nb) {
  switch (direction) {
    case HAUT:
      return ligneJoueur-nb;
      break;
    case BAS:
      return ligneJoueur+nb;
      break;
    default:
      return ligneJoueur;
      break;
  }
}

// fonction colonneSuivante
int cs(int direction, int nb) {
  switch (direction) {
    case DROITE:
      return colonneJoueur + nb;
      break;
    case GAUCHE:
      return colonneJoueur -nb;
      break;
    default:
      return colonneJoueur;
      break;
  }
}

void deplace(int dir) {
...

 

On peut donc maintenant déplacer le joueur dans le jeu et pousser des caisses.

Le programme maintenant réalisé est disponible ici:

https://github.com/Papamaker/kitco/blob/master/lib/src/sokoban/sokobanEtape2/sokobanEtape2.ino

Pour la prochaine étape, rendez-vous ici

Publicités