Programmation orientée objets dans Processing : faire une animation neige sur une image

Avec Processing, à la fois logiciel et langage de programmation libre et open source (processing.org), il est possible de réaliser une animation en manipulant des objets, comme un filtre pluie sur une image. En modifiant assez peu de choses à ce premier exercice, nous pouvons remplacer la pluie par de la neige pour illustrer par exemple une scène de Noël.

Scène de Noël animée avec un filtre Processing


Cette animation repose sur une image. Il faut déterminer la taille de celle-ci pour définir les paramètres du programme. L'image utilisée ("scene.png"), au format PNG, fait 600 pixels en largeur et 424 en hauteur. Pour faire une animation, nous allons utiliser la fréquence d'une vidéo (24 images par seconde ⇒ frameRate = 24).

Image de fond de l'animation de 600 x 424 pixels

Les flocons de neige - les objets du programme - sont réalisés en dessinant 3 ellipses superposées (pour donner un effet de flou au flocon) sans contour avec un remplissage blanc de faible opacité : fill(255, 75);
La première valeur de remplissage défini la couleur (255 = blanc, lorsque les trois valeurs RVB sont identiques, on obtient une valeur de gris que l'on peut indiquer avec un seul nombre). La deuxième valeur défini l'opacité : ici 75 sur un maximum possible de 255.

On décrit donc notre objet dans une classe Flocon comme ceci :

class Flocon {
  // variables de l'objet
  float floconX, floconY, diametre, vitesseY;
  // variables propres à chaque flocon
  Flocon(float tempX, float tempY, float tempD) {
    floconX = tempX;
    floconY = tempY;
    diametre = tempD;  
  }
    // dessin d'un flocon (3 ellipses de plus en plus petites)
    void display() {
      fill(255, 75);
      noStroke();
      ellipseMode(CENTER);
      ellipse(floconXfloconY, diametre, diametre);
      ellipse(floconXfloconY, diametre*3/4, diametre*3/4);
      ellipse(floconXfloconY, diametre/2, diametre/2);
    }
    /* mouvement du flocon : la vitesse de la chute dépend de sa taille, quand un flocon est descendu en dessous du bas de l'écran, on le renvoie au dessus pour recommencer une nouvelle chute (l'emplacement est fixé de manière relativement aléatoire) */
    void chute() {
      vitesseY = diametre/4;
      floconY = floconY + vitesseY;
      floconX++;
      if(floconY > height + diametre) {
        floconY = random(-50, -diametre);
        floconX = random(-200, width);
      }
    }
}


Pour utiliser les objets Flocon dans le programme Processing, nous créons un tableau qui contiendra les objets (nommé ici "flocons") lorsque l'on défini l'ensemble des variables. Dans le setup(), on crée chaque flocon du tableau avec une boucle for. Dans la partie draw(), une nouvelle boucle for permet l'affichage de chaque flocon de neige à l'écran.

Code de l'animation :

PImage image;
Flocon[] flocons = new Flocon[500];

void setup() {
  size(600, 424);
  smooth();
  frameRate(24);
  image = loadImage("scene.png");
  for(int i = 0; i < flocons.length; i++) {
    flocons[i] = new Flocon(random(-50, width), random(height),  random(10));
  }
}

void draw() {
  background(image);
  // background(0, 255, 0);
  for(int i = 0; i < flocons.length; i++) {
    flocons[i].display();
    flocons[i].chute();
  }
}

class Flocon {
  float floconXfloconY, diametre, vitesseY;
  
  Flocon(float tempX, float tempY, float tempD) {
    floconX = tempX;
    floconY = tempY;
    diametre = tempD;
  }
    
    void display() {
      fill(255, 75);
      noStroke();
      ellipseMode(CENTER);
      ellipse(floconXfloconY, diametre, diametre);
      ellipse(floconXfloconY, diametre*3/4, diametre*3/4);
      ellipse(floconXfloconY, diametre/2, diametre/2);
    }
    
    void chute() {
      vitesseY = diametre/4;
      floconY = floconY + vitesseY;
      floconX++;
      if(floconY > height+diametre) {
        floconY = random(-50, -diametre);
        floconX = random(-200, width);
      }
    }
}

Pour enregistrer les images de notre animation afin d'en faire une image de type GIF animé, ajoutez le code suivant avant la fin de la boucle draw() :

saveFrame("tombelaneige###.png");

Avec cette ligne de code, le programme enregistrera, pendant tout le temps que se jouera l'animation, l'image de la fenêtre ("frame") à chaque fois que l'écran se rafraîchira (soit à chaque mouvement des flocons de neige). C'est-à-dire qu'à chaque calcul du processeur, une nouvelle vue s'affiche et s'enregistre dans un nouveau fichier PNG. Les dièses ("#") figurent chacun l'emplacement d'un chiffre, les fichiers étant numérotés par Processing à chaque enregistrement.

Il est maintenant facile, à l'aide du logiciel de retouche d'image GIMP, de créer une image GIF : Faites "Ouvrir en tant que calques..." (Ctrl + Alt + O) et sélectionnez toutes les images PNG de votre animation (en maintenant la touche Maj enfoncée).

Pour visionner l'animation, vous pouvez sélectionner le menu "Filtre / Animation / Rejouer l'animation". Dans ce même menu, choisissez "Filtre / Animation / Optimiser (pour GIF)" pour réduire le poids du futur fichier.

Vous pouvez alors exporter votre GIF avec la commande Ctrl + E ou "Fichier / Exporter". N'oubliez pas, après avoir défini le format de fichier d'export, de cocher "En tant qu'animation" et de paramétrer le délai entre chaque image en millisecondes (environ 42 millisecondes de délai pour obtenir une fréquence de près de 24 images / secondes).

Commentaires

Posts les plus consultés de ce blog

Débuter avec les dégradés de couleurs dans Inkscape

Pour les débutants : 3 méthodes faciles pour créer un texte incurvé dans Inkscape

Pour les débutants : utiliser les guides dans le logiciel Inkscape pour préparer une animation