Sites


PROCESSING - 2

Les astuces

Pour vous éviter certaines erreurs de base et aller plus loin dans l'utilisation de Processing, ce chapitre présente plusieurs astuces et morceaux de code qui permettent de résoudre une série de problèmes fréquemment rencontrés. N'hésitez pas à les utiliser dans vos programmes.

Augmenter la mémoire

Si vous créez des sketchs qui utilisent de la vidéo, de nombreuses images ou qui travaillent avec des données volumineuses, il peut arriver que votre programme génère une erreur pour cause de mémoire insuffisante. Voici l'erreur affichée par Processing dans la console.

erreurs_1

Pour résoudre ce problème, vous devez ouvrir les préférences de Processing et changer la quantité de mémoire allouée à votre sketch.

Memory

Inverser la valeur d'un booléen (vrai/faux)

Voici un mécanisme permettant d'inverser la valeur d'un booléen sans avoir à tester à l'aide de la condition if/ then si sa valeur est vraie ou fausse . Cette astuce repose sur le fait qu'en précédant la valeur booléenne d'un point d'exclamation, on obtient son contraire.

boolean afficheInfo;

void setup() {
  afficheInfo = false;
}

void draw() {
  background(0);
  // Si vrai, on affiche le texte
  if (afficheInfo) text("Info", 10, 20);
}

void keyPressed() {
   // on affecte à afficheInfo l'inverse de sa valeur actuelle
   afficheInfo = ! afficheInfo;
}

Intervalomètre avec frameRate(), frameCount et modulo

Si l'on souhaite effectuer une action à intervalle régulier, le procédé le plus simple consiste à utiliser les méthodes de comptage d'images de Processing : frameRate(), frameCount ainsi que la commande % (modulo). Notez que cette astuce ne permet de gérer qu'un seul intervalle de temps par programme. Détaillons chacune des ces fonctions :

  • la variable frameCount permet de connaître le nombre de fois où draw() a été appelé depuis le lancement du programme.
  • frameRate() fixe la fréquence des appels à draw() par seconde (par défaut 30).
  • l'opérateur % (modulo) retourne le reste de la division de deux nombres, ce reste étant strictement inférieur au nombre diviseur (c'est une règle mathématique!). Ainsi 7%3 retourne 1 ou encore 8%2 retourne 0. L'opérateur modulo permet de compter sans jamais dépasser un certain nombre (la base du modulo).

Ainsi, si l'on veut effectuer une action toutes les secondes, on la déclenchera dans le cas où le reste de la division de frameCount par la valeur passée à frameRate() est bien égal à zéro. Dans l'exemple qui suit, nous changeons la couleur de fond chaque seconde en vérifiant que notre compteur est un multiple de 24.

color couleur;

void setup() {
  couleur = 0;
  frameRate(24);
}

void draw() {
  background(couleur);
  if (frameCount % 24 == 0) {
     couleur = (int) random(255);
  }
}

Exercice : modifiez le code ci-dessus pour que le changement de couleur ait lieu toutes les 3 secondes.

Créer une classe intervalomètre

Dans l'astuce précédente, nous avons vu comment créer un intervalomètre simple, très utile pour exécuter une action à intervalle régulier, mais qui comporte certaines limitations. A présent, nous allons apprendre à programmer un intervalomètre gérant plusieurs intervalles de temps au sein d'un même sketch, et ce, avec précision (sans variation de vitesse lorsque votre ordinateur est occupé à exécuter simultanément de nombreuses tâches). A titre d'illustration, nous allons créer un objet Intervalometre chargé d'exécuter un bloc de code à un intervalle régulier. Le système de comptage fonctionne sur le principe suivant : mémoriser le moment auquel l'objet a été exécuté pour la dernière fois et à chaque appel de la méthode draw() de vérifier si le temps actuel est plus grand que ce moment de temps antérieur auquel on a ajouté un intervalle donné. Nous allons nous aider de la méthode millis() qui retourne le nombre de millisecondes depuis le lancement du programme.

Notre classe sera composée de deux caractéristiques et d'une action :

  • L'intervalle de temps (un intervalle que vous aurez déterminé à votre convenance)
  • Le temps de la dernière vérification de l'intervalomètre
  • Une action qui vérifie si le prochain intervalle a été franchi.
class Intervalometre {
  int intervalle;
  int dernier_tic;

  Intervalometre(int intervalle_initial) {
    intervalle = intervalle_initial;
    dernier_tic = millis();
  }

  boolean verifierIntervalle() {
    if (millis() > dernier_tic + intervalle) {
      dernier_tic = millis();
      return true;
    } else {
      return false;
    }
  }
}

Ici, la méthode verifierIntervalle() vérifie si l'intervalle de temps est écoulé depuis la dernière fois. Elle retourne vrai ou faux. En d'autres termes, cela revient à décider d'exécuter une certaine action à chaque fois que notre horloge fait tic.

La dernière étape de programmation de notre sketch va consister à déclarer une variable qui stockera notre intervalomètre. Chaque appel de la méthode draw() exécutera verifierIntervalle() de notre objet Intervalometre. Si cette méthode nous retourne vrai, nous allons faire apparaître un rectangle positionné au hasard sur l'écran. L'intervalle de temps choisi dans cet exemple est de 100 millisecondes.

Intervalometre intervalometre;

void setup() {
  intervalometre = new Intervalometre(100);
}

void draw() {
  if (intervalometre.verifierIntervalle()) {
    rect(random(0, width), random(0, height), 10, 10);
  }
}

Suspendre la répétition de draw()

Tant que l'on n'a pas quitté le programme, et sauf indication expresse de notre part, la fonction draw() est appelée en boucle durant toute l'exécution du programme. Il existe cependant un moyen d'interrompre ce cycle à l'aide de la fonction noLoop(). La fonction loop() a l'effet inverse.

L'exemple suivant montre comment interrompre et reprendre ce mouvement à l'aide de la touche 's' et de la barre d'espacement.

int position = 0;
int increment = 1;

void setup() {
}

void draw() {
  background(0);
  ellipse(50, position, 5, 5);
  // on déplace le point de 1 pixel
  position += increment;
  // si on touche les bords
  if (position > height || position < 0) {
   // alors on inverse la valeur d'incrément
   increment *= -1;
  }
}

void keyPressed() {
 if (key == ' ') {
  // on relance le cycle
  loop();
 }
 else if (key == 's' || key == 'S') {
  // on arrête le cycle 
  noLoop();
 }
}

Quitter le programme

Pour quitter un programme en utilisant du code plutôt qu'une intervention utilisateur, vous pouvez appeler la méthode exit().

// Vous pouvez ajouter ce code à l'exemple précédent
else if (key == 'e' || key =='E') {
  exit(); // on quitte le programme
}

Il y a une erreur de communication avec le serveur Booktype. Nous ne savons pas actuellement où est le problème.

Vous devriez rafraîchir la page.