Formations à l'informatique et à l'électronique

Auteur : SD
Créé le : 19-02-2015

Premiers pas avec Processing

Logo Processing

Conçu par des artistes, pour des artistes, Processing est un des principaux environnements de création utilisant le code informatique pour générer des oeuvres multimédias sur ordinateur. L'attrait de ce logiciel réside dans sa simplicité d'utilisation et dans la diversité de ses applications : image, son, applications sur Internet et sur téléphones mobiles, conception d'objets électroniques interactifs. Le langage utilisé est le Java et il est possible de porter les applications sur Android.

Processing est disponible pour Windows, Linux et MacOS. Il est téléchargeable sur le site officiel : https://processing.org/download/ ou directement sur electro.info.free.fr :

Dessiner

Ouvrir l'exemple "ShapePrimitives" (File => Examples... puis : Basics => Form => ShapePrimitives).

Lancer l'exécution : Sketch => Run

Une référence complète du langage est disponible à cette adresse : http://www.processing.org/reference/

Remarque : Vous disposez également d'une version "hors ligne" de cette référence sur votre disque dur dans le dossier d'installation de Processing :

La référence du langage Processing est disponible hors ligne

Modifier le code du programme comme indiqué ci-dessous :

size(displayWidth, displayHeight);

noStroke();
smooth();

background(51);

fill(255,0,0);
triangle(18, 18, 18, 360, 81, 360);

fill(0,255,0);
rect(81, 81, 63, 63);

fill(0,0,255);
quad(189, 18, 216, 18, 216, 360, 144, 360);

fill(0,255,255);
ellipse(252, 144, 72, 72);

fill(255,255,0);
triangle(288, 18, 351, 360, 288, 360);

fill(255,255,255);
arc(479, 300, 280, 280, PI, TWO_PI);

Lancer l'exécution : Sketch => Run

Remarque : Il est possible de réaliser un rendu 3D (voir box et sphere).

A partir de ce que vous avez pu observer et de la référence du langage, expliquer en Français le rôle des fonctions :

Où se situe le point de coordonnées 0,0 de la fenêtre ?

Placer du texte

Ajouter les lignes ci-dessous à la fin de votre programme :

textSize(32);

fill(0,255,0,127); // Couleurs RVB + Transparence
text("Texte à la position 30,30", 30, 30);
fill(0,0,255); // Couleurs RVB
textAlign(RIGHT);
text("Texte en bas à droite!",displayWidth,displayHeight);

String s = "La valeur de i est : ";
int i = 2345;
fill(240,240,240);
textAlign(CENTER,CENTER);
text(s+i,displayWidth/2,displayHeight/2); // Le nombre i est convertit en texte et concaténé avec s

Lancer l'exécution : Sketch => Run

Que représente le type "String" ?

Quel opérateur a permit de concaténer les variables s et i ?

Faire bouger les éléments

Algorigramme de l'exécution d'un programme processing

Jusqu'à maintenant les programmes exécutés étaient linéaires : une fois leur exécution terminée ils s'arrêtent.

Pour avoir un programme qui s'exécute en permanence, la structure habituelle d'un programme Processing est celle présenté ci-contre :

  • La fonction setup() est exécutée une seule fois, comme son nom l'indique elle est utilisée pour initialiser l'application.
  • La fonction draw() est exécutée en boucle (60 fois par seconde, cette valeur est modifiable).

Remarque : Cette structure rappelle celle d'un programme Arduino.

Créer un nouveau programme et copier le code ci-dessous :

// Variables globales pour la balle
int ball_x; // Position de la balle
int ball_y;
int ball_dir_x = 10; // Vitesse de la balle en x
int ball_size = 20;

void setup()
{
size(displayWidth,displayHeight); // Application en plein écran
noStroke(); // Ne pas afficher les contours
smooth(); // Amélioration de la qualité des graphiques
ball_y = height/2; // Position initiale de la balle
ball_x = 1;
background(51);
frameRate(30); // Vitesse de draw() : 30 fps
}

void draw()
{
background(51); // Couleur du fond en nuance de gris (0:Noir 255:Blanc)
// L'appel de cette fonction efface l'écran
ball_x += ball_dir_x; // Déplacement de la balle en x

DetectionFinEcran();

// Dessine la balle
fill(255);
ellipse(ball_x, ball_y, ball_size, ball_size);
}

void DetectionFinEcran()
{
if (ball_x > width)
{ // Si la balle arrive au bout de l'écran
ball_x = 0 - ball_size; // une autre arrive à gauche
ball_y = int(random(0,height)); // Sa position y est aléatoire
}
}

Lancer l'exécution : Sketch => Run

Quel est le type de la fonction "DetectionFinEcran" ?

Combien de paramètre(s) prend la fonction "DetectionFinEcran" ?

Quelle est la portée des variables "ball_x" et "ball_size" ?

Modifier le programme de telle sorte que la balle se déplace en diagonale (à 45°) et rebondisse à 90° sur les bords de l'écran.

Créer une fonction séparée pour la gestion des rebonds.

Compter les rebonds et afficher leur nombre en haut à gauche de l'écran.

Insérer votre programme dans votre rapport (Astuce : vous pouvez copier/coller votre code dans un traitement de texte en conservant les couleurs en sélectionnant le code et en le copiant avec le raccourcis CTRL+Maj+C).

Utilisation d'un tableau à deux dimensions

Dans cette partie nous allons ajouter des obstacles qui seront placés aléatoirement sur l'écran. Leur position (x,y) sera mémorisé dans un tableau à deux dimensions qui aura donc 2 colonnes et autant de lignes que d'obstacles.

Ajouter, les différents morceaux de code ci-dessous à votre programme précédent :

// Déclaration des variables globales
...
// Variable globales pour les obstacles
int colonnes = 2; // Nombre de colonnes
int lignes = 10; // Nombre de lignes
int nbObstacle = 0; // Nombre actuel d'obstacles
int tailleObstacle = 50; // Taille des obstacles
int[][] tabObstacles; // Déclaration d'un tableau d'entiers à deux dimensions
...
void setup() {
// Code de la fonction setup()
...
tabObstacles = new int[colonnes][lignes]; // Création du tableau des obstacles

for(nbObstacle=0; nbObstacle<lignes; nbObstacle++) { // Initialisation aléatoire de la position des obstacles
tabObstacles[0][nbObstacle]=int(random(tailleObstacle,displayWidth-tailleObstacle));
tabObstacles[1][nbObstacle]=int(random(tailleObstacle,displayHeight-tailleObstacle));
}
...
}

void draw() {
// Code de la fonction draw()
...
//Dessine les obstacles
fill(255,0,0);
for(int i=0; i<nbObstacle; i++) {
ellipse(tabObstacles[0][i], tabObstacles[1][i], tailleObstacle, tailleObstacle);
}
...
}

Vérifier que le code fonctionne (les obstacles s'affichent mais la balle passe dessous sans rebondir dessus).

Modifier votre code de telle sorte que la balle rebondisse sur les obstacles. Pour simplifier, on ne tiendra pas compte de l'angle d'impact entre la balle et l'obstacle : la balle repartira simplement dans le sens contraire à son déplacement en cas de collision (voir vidéo de démonstration).

Pour la détection des collisions, on utilisera la formule ci-dessous (Théorème de Pythagore) :

Graphique et formule du calcul de la distance entre 2 points dans un plan
Pour les fonctions mathématiques, voir : fonction sq() et fonction sqrt().

Insérer votre programme dans votre rapport

Interactions avec l'utilisateur

La souris et le tactile

La variable mousePressed de type booléen (vrai ou faux) permet de savoir si un bouton de la souris est appuyé (ou appuie sur écran tactile) à un instant t.

La fonction void mousePressed() est appelée à chaque fois qu'un bouton de la souris est appuyé (ou appuie sur écran tactile). Il est possible de savoir quel bouton a été appuyé grâce à la variable mouseButton. Il suffit d'implémenter cette fonction dans votre code comme dans l'exemple ci-dessous :

// Déclaration des variables globales
...

void setup() {
// Code de la fonction setup()
...
}

void draw() {
// Code de la fonction draw()
...
}

void mousePressed() {
// Code de la fonction mousePressed()
// Ce code sera exécuté à chaque appuie sur un des boutons de la souris
...
}

Les variables mouseX et mouseY nous donnent à tout moment les coordonnées du dernier appuie sur l'écran tactile ce qui est suffisant pour gérer les interactions avec l'utilisateur.

Modifier le programme pour afficher en haut à gauche, en dessous du nombre de rebonds, les coordonnées X,Y du dernier appuie sur l'écran (dernier clic).

Ajouter une barre verticale bleue à la position X du dernier clic (largeur de la barre : 5 pixels). La balle doit rebondir sur cette barre comme si celle-ci était le bord de l'écran (voir vidéo de démonstration).

Insérer votre programme dans votre rapport

Capture d'écran sélection mode Android dans processing

Le son

Cette partie est destinée à Android, il faut donc utiliser le mode Android.

L'exemple de code ci-dessous montre comment déclarer, initialiser et jouer une musique en boucle (http://developer.android.com/reference/android/media/MediaPlayer.html).

// Importation des libraries
import android.media.*;
import android.content.res.*;

// Variable globale pour le media player
MediaPlayer snd;

// à placer dans le code pour lancer la musique
try {
MediaPlayer snd = new MediaPlayer();
AssetManager assets = this.getAssets();

// Le fichier tetris.mp3 doit être placé dans le dossier data du projet
AssetFileDescriptor fd = assets.openFd("tetris.mp3");
snd.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
snd.prepare();
snd.setLooping(true);
snd.start();
}

catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (IllegalStateException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}

Coder 2 fonctions : StartMusic() et PauseMusic(). Vous pouvez vous aider du diagramme d'état de la documentation Android.

StartMusic() sera appelé au lancement de l'application et PauseMusic() sera appelé quand la balle aura effectué 15 rebonds. La musique reprendra lorsque la balle aura fait 20 rebonds.

Depuis la version 3 de Processing, une bibliothèque "Sound" est disponible, elle ne nécessite pas le mode Android. Pour installer cette bibliothèque, aller dans le menu "Sketch" => "Importer une librairie..." => "Ajouter une librairie..."

Vous pouvez télécharger des sons gratuitement sur les sites ci-dessous :

Le vibreur

Cette partie est également destinée à Android, il faut donc utiliser le mode Android et bien entendu, le simulateur ne pouvant pas vibrer, exécuter le programme sur une tablette.

L'exemple de code ci-dessous montre comment déclarer, initialiser et faire tourner le vibreur.

// Importations des classes pour le vibreur
import android.content.Context;
import android.app.Notification;
import android.app.NotificationManager;
import android.view.MotionEvent;

// Variables globales pour le vibreur
NotificationManager gNotificationManager;
Notification gNotification;
long[] gVibrate = {0,100};

void setup() {
...
// Initialisations à placer dans setup()
gNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
gNotification = new Notification();
gNotification.vibrate = gVibrate;
...
}

// à placer dans le code pour faire vibrer
gNotificationManager.notify(1, gNotification);

Faire vibrer la tablette à chaque fois que la balle rebondit.

Vidéo de démonstration

Cette vidéo montre le résultat attendu suite aux différentes modifications demandées :

Pour aller plus loin

Voici quelques idées de modifications supplémentaires :

Webographie

https://processing.org/reference/
http://developer.android.com/reference/android

Vous avez apprécié cet article ? Partagez le !

Article connexe : Les structures algorithmiques de base