Je prépare un travail avec Processing qui va nécessiter de faire bouger des formes assez nombreuses dans le canevas. Ces formes peuvent être générées par le sketch ou être des fichiers svg (ou png) associés au sketch. J’explore donc les moyens de les générer puis de les faire bouger. Cet article reprend mes étapes successives d’apprentissage.

Etape 1 : explorer la notion de classe d’objet

D’abord tester la notion de classe et créer manuellement des objets

J’ai utilisé le script proposé dans l’exercice 2 du Chapitre 8 sur les objets de Learning Processing de Daniel Shiffman.

Ce que j’en retiens :

Une classe d’objet est utilisée lorsqu’on programme en mode orienté objet. La classe contient toujours les éléments suivants :

// des variables

// un constructor

// des fonctions, dont celle qui affichera l’objet (void display() mais pas obligatoirement ce nom)

La convention est toujours de faire commencer le nom d’une classe par une lettre majuscule, comme ici Car.

Ensuite, utiliser un array pour créer et animer un grand nombre d’objets à partir d’une classe

J’ai testé le code proposé dans l’exercice 9 du Chapitre 9 sur les « arrays » (tableaux) de Learning Processing de Daniel Shiffman.

Avec une seule classe on peut créer un nombre infini d’objets semblables, la limite étant la capacité de l’ordinateur à générer et animer ces objets.

Etape 2 : explorer le mouvement « autonome » d’objets divers

D’abord créer des objets divers et les faire bouger de manière « autonome »

Je me suis inspirée des essais de l’étape 1 et de l’exercice 2 du Chapitre 10 sur les algorithmes de Learning Processing de Daniel Shiffman.

Le script avec les classes dans des fichiers distincts en format zippé : alObjets3_Knowledge alObjets3 (zip)

.

Dans ce script, je crée « manuellement » un objet « myCar1 » et un objet « myVelo1 » et les objets balls[0] à balls[MaxBalls] sont générés par un array.

On notera qu’ici les paramètres de chaque objet sont définis dans les classes et pas dans le programme principal (voir plus bas).

Ensuite, tester la gestion des interactions entre certains objets

Je me suis inspirée de l’exercice 3 du Chapitre 10 sur les algorithmes de Learning Processing de Daniel Shiffman.

Dans ce sketch, les balles s’arrêtent lorsqu’elles approchent un « vélo » du fait d’une fonction intersect(Velo b) définie dans la classe Ball. Dans le programme principal, fonction void draw(), les balles ne bougent que si la distance au vélo est suffisante par le biais de :

if ( !balls[i].intersect(myVelo1) && !balls[i].intersect(myVelo2) ) {
     balls[i].move(); 
}

Le script avec les classes dans des fichiers distincts en format zippé : alObjets3 (zip)

.

Etape 3 : Explorer une classe pour le chronométrage et la gestion du temps

J’ai lu quelque part que le système utilisé pour l’étape 2 peut consommer énormément de ressources si on crée beaucoup d’objet. J’ai donc souhaité chronométrer le processus. Pour celà j’ai utiliser une classe « Timer » inspirée encore une fois du livre Learning Processing de Daniel Shiffman : exemple 4 et exemple 5 (timer OOP ou Programmation Orientée Objet) du chapitre 10.

Ca donne ce programme : alObjets5 (zip). Il est identique au précédent sauf que la console affiche le temps écoulé en fonction d’un compteur.

Etape 4 : utilisation de PShape

Dans ce tutoriel de Processing.org sur PShape, Daniel Shiffman explique que PShape est une solution pour éviter de saturer les capacités de l’ordinateur lorsqu’on veut créer un grand nombre de formes. J’ai donc décidé d’explorer PShape.

Je me suis inspirée du tutoriel et de Je me suis inspirée de File → Examples → Topics → Create Shapes → PolygonPShapeOOP que l’on trouve dans les exemples de Processing.

Ce script (alObjets6 (zip)) crée des étoiles comme indiqué dans le tutoriel ci-dessus et les déplace sur l’écran. J’ai ensuite créé des balles sur le même principe qui se déplacent comme dans alObjets5 de l’étape 3. Il y a aussi un chronomètre qui mesure le temps toutes les 100 boucles de draw().

Je ne peux pas afficher le résultat ici car l’extension que j’utilise ne gère pas correctement createShape et ça provoque une erreur dans la page. J’ai créé une version JavaScript (cf étape 8 pour la visualisation).

Syntaxe pour les objets prédéfinis et les objets à construire

La construction des objets PShape n’utilise pas exactement la même syntaxe lorsque l’objet est prédéfini (ici ellipse) ou pas (ici pour l’étoile) :

Dans la classe Star

createShape()

 // code de construction de la forme, morceau par morceau

beginShape()

s.fill(105, 204);

 s.noStroke();

endShape(CLOSE)

et dans la classe Ball

createShape(ELLIPSE, x, y, r*2, r*2);

b.setStroke(false) ;

b.setFill( c );

PShape manipule l’origine (0,0) du canevas

L’utilisation de PShape manipule l’origine (0,0) du canevas et il faut faire bien attention au moment du setup. J’ai mis beaucoup de temps à comprendre pourquoi mon canevas paraissait décalé. Puis en relisant pour la énième fois le tutoriel sur PShape, j’ai vu cette petite phrase : « when using PShape, what we’re really doing is configuring the geometry relative to the origin (0,0) » et j’ai enfin compris le sens des exemples qui suivaient !

Dans la fonction setup() on doit construire la forme à l’origine du canevas (0,0). Ainsi si je crée un rectangle avec PShape, je vais utiliser le code suivant (positionnement du rectangle dans la fonction setup à 0,0 :

PShape rectangle;

void setup() {

  size(640,360,P2D);

  rectangle = createShape(RECT, 0, 0, 100, 50);

}

void draw() {

  background(51);

  translate(mouseX,mouseY);

  shape(rectangle);

}

 

Par contre, si je décide de positionner les objets par leur centre (avec shapeMode(CENTER); ) c’est plus compliqué, je n’ai pas compris comment faire.

La façon d’afficher les objets est différente

Maintenant la fonction display() utilise des nouvelles fonctions :

void display() {

	pushMatrix();
	translate(x, y);
	shape(b);
	popMatrix(); 
}

pushMatrix() et popMatrix() assurent le changement d’origine du canevas et son retour aux coordonnées initiales.

Etape 5 : manipulation de PShape par des variables définies dans le programme principal

La version 7 de alObjets ne crée plus que des balles (pas les étoiles) et les variables sont définies à l’intérieur de la classe, ce qui limite un peu les choses.

Télécharger la version 7 : alObjets7 (zip)

Dans cette version 8, je m’inspire du cours sur la Programmation Orientée Objet de Margaret Noble, une artiste et professeur d’art. Elle explique très clairement le fonctionnement des classes puis vers la fin, elle expose comment on peut transférer des variables du programme principal vers les classes en utilisant des variables _var  au lieu de var .

Télécharger la version 8 : alObjets8 (zip)

Je ne peux pas afficher le résultat ici car l’extension que j’utilise ne gère pas correctement createShape et ça provoque une erreur dans la page.

J’ai converti un mix du code de alObjets6.pde et alObjets8.pde en Javascript (librairie p5.js). Si vous voulez voir le contenu de ce fichier, vous pouvez le télécharger  : alObjets6_convertiJS (en p5.js)

En voici le résultat dans CodePen

See the Pen Moving stars (p5.js) by Delpech (@aldelpech) on CodePen.

Et maintenant ?

J’ai compris comment génerer et contrôler des formes via des classes et PShape.

Maintenant, je veux faire la même chose sur des images svg. En attendant, je vais aussi voir comment convertir un script processing en javascript pour pouvoir en présenter une version animée en utilisant codepen.

1 1 vote
Évaluation de l'article
0
Nous aimerions avoir votre avis, veuillez laisser un commentaire.x