tite fractale

Prise en main de Processing

1. Introduction

Dans cette activité, nous allons reconstituer un des jeux vidéos les plus anciens : Pong (voir l’article Wikipedia), avec le langage Processing.

pong

Processing, d’abord créé par des artistes et pour des artistes, est devenu très populaire dans beaucoup de domaines mais aussi dans l’enseignement. Voir cet article sur Floss Manuals.

Processing peut être utilisé en ligne ou installé localement en le téléchargeant ici.

2. setup() et draw()

Ce sont les deux fonctions principales de Processing pour créer une animation.

Il ne faut jamais appeler vous-même ces fonctions avec setup() ou draw(), c’est le système de Processing qui s’en occupe. Notre travail, c’est de définir ces fonctions.

void setup() {
    ... ici du code ...
}

void draw() {
    ... ici du code ...
}

3. Une balle sur le terrain

size(w, h) définit la taille de la fenêtre (il faut lui donner des entiers) et ellipse(cx, cy, dx, dy) dessine une ellipse. Quelle fonction mettre dans setup, quelle fonction mettre dans draw ?

Trop facile !

Comment dessiner un cercle ?

Rendre les deux diamètres égaux.
// Pong

void setup() {
    size(400, 300);
}

void draw() {
    ellipse(200, 150, 50, 50);
}

4. Déplacement de la balle

4.1. Variables

C’est l’association entre un nom et une valeur. Nous appelleront x et y les coordonnées de la balle car si on veut que la balle bouge, il faut que ses coordonnées varient.

Le type float est le plus proche des nombres réels.

On déclare les variables en tête de fichier, avant setup. Ensuite il faut les initialiser dans setup (leur donner une première valeur). Si on ne les initialise pas, elles sont initialisées par défaut à 0. Ensuite, on remplace les coordonnées fixes du centre de l’ellipse par x et y,

Une déclaration, une initialisation et le remplacement peuvent sembler être une perte de temps, mais c’est ainsi que le mouvement va naître !

// Pong

float x; // abscisse du centre de l’ellipse
float y; // ordonnée

void setup() {
    size(400, 300);
    x = 200;
    y = 150;
}

void draw() {
    ellipse(x, y, 50, 50);
}

4.2. Mouvement

Les variables x et y doivent être modifiées. Dans quelle fonction, setup ou draw ?

Dans draw.

Comment s’y prendre pour stocker une nouvelle valeur dans les coordonnées du centre de la balle, disons 3 de plus que l’ancienne valeur ?

Grâce à ce que l’on appelle une incrémentation : ma_variable = ma_variable + augmentation.

Sauf que la balle laisse une « trace ». Il faut effacer l’écran pour faire place nette avant chaque image avec background(code_monochrome).

// Pong

float x; // abscisse du centre de l’ellipse
float y; // ordonnée

void setup() {
    size(400, 300);
    x = 200;
    y = 150;
}

void draw() {
    x = x + 3;
    y = y + 3;
    background(0);
    ellipse(x, y, 50, 50);
}

Quelle particularité possède le repère géométrique de Processing ? En fait, en informatique, la plupart des repères sont orientés ainsi. Devinerez-vous pourquoi ?

Les ordonnées croissantes sont vers le bas. Cela correspond aux directions de lecture des occidentaux : de gauche à droite puis de haut en bas.

5. Rebonds

5.1. Analyse du problème

Quand ont lieu les rebonds ? Donner des valeurs de x et y pour lesquelles vous voudriez que la balle change de direction ?

à 500?, un peu avant?, un peu après? utilisation inégalité plutôt qu’égalité.

=> Structure conditionnelle

if (condition) {
    code à exécuter;
}

5.2. Le code

Puisque l’on veut modifier la vitesse, il faut en faire une variable. On appellera vitesse_h la vitesse horizontale de la balle et vitesse_v la vitesse verticale.

Quatre murs -> quatre conditions.

// Pong

float x; // abscisse du centre de l’ellipse
float y; // ordonnée
float vitesse_h; // vitesse horizontale de la balle
float vitesse_v; // vitesse verticale

void setup() {
    size(400, 300);
    x = 200;
    y = 150;
    vitesse_h = 3;
    vitesse_v = 3;
}

void draw() {
    if (x >= 375) {
        vitesse_h = -vitesse_h;
    }
    if (y >= 275) {
        vitesse_v = -vitesse_v;
    }
    if (x <= 25) {
        vitesse_h = -vitesse_h;
    }
    if (y <= 25) {
        vitesse_v = -vitesse_v;
    }
    x = x + vitesse_h;
    y = y + vitesse_v;
    background(0);
    ellipse(x, y, 50, 50);
}

6. Factorisations

Quand on programme, on cherche toujours à éviter de se répéter. Voir cet article Wikipedia pour plus de détails, mais le mot « factorisation » a le même sens qu’en mathématiques.

$$2×3 + 2×4 = 2(3 + 4)$$

6.1. Factorisation des conditions

On se rend compte que le choc sur les murs de gauche et de droite a le même effet. Comment regrouper les deux conditions qui correspondent à ces murs ?

Grâce à un OU logique. if ((x >= 375) || (x <= 25)) {...}

6.2. Factorisation des dimensions

Que faire si on veut jouer avec une balle plus petite, disons de 30 pixels de diamètre ? Et avec une fenêtre de taille différente, plus grande si l’on veut jouer sur le grand écran du salon, plus petite si l’on veut jouer sur un téléphone ?

Écrire un programme où aucune valeur n’est « hardcodée » dans la fonction draw.

7. Raquette

7.1. Forme et déplacement

rect(_, mouseY, _, _) afin que la raquette suive la souris.

Comment affiner les coordonnées des coins de la raquette pour que le pointeur de la souris soit au centre du rectangle qui la représente ? Rappelez-vous ! Pas de valeurs codées en dur dans draw !

7.2. Collision

Besoin d’opérateurs logiques.

&& pour la conjonction (ET)

Que changer dans le mouvement de la balle (retour total ou rebond

8. Personnaliser les couleurs

8.1. Le fond

Penser à une couleur pour le fond et essayer de l’obtenir en changeant background(int) par background(int, int, int).

8.2. La balle

fill(int, int, int) décide la couleur des prochains objets dessinés. Essayer de dessiner une balle jaune et une raquette bleue.

9. Approfondissement

9.1. Autres idées

À vous de jouer, à vous d’implémenter vos idées (score à afficher avec text(str, int, int), changement de couleurs à chaque rebond…).

9.2. D’autres tutoriels

10. Memento

Un memento plus complet est disponible ici. Il pointe vers différentes références.

// Tout ceci qui suit "//" sur une même ligne est un commentaire.
// Processing n'en tient pas compte.

setup(){                // Les actions situées entre les accolades de cette fonction
                        // ne sont effectuées qu'une seule fois au démarrage du sketch.
}
draw(){                 // Les actions situées entre les accolades de cette
                        // fonction sont effectuées en boucle jusqu'à fin du sketch.
}

size(800,600);          // Fixe la taille de la fenêtre:
                        // 800 pixels horizontalement et 600 verticalement.
ellipse(cx,cy,dx,dy);   // Dessine une ellipse de centre (cx,cy)
                        // de diamètres dx et dy (nombre de pixels sur
                        // l'horizontale et sur la verticale).
                        // Attention, les y croissants vont vers le bas.

float mavar;            // Déclare la variable nommée mavar, de type flottant (réel).
mavar = 10.0;           // La variable réelle de nom mavar reçoit la valeur 10.0.
int monautrevar;        // Idem avec monautrevar, de type entier.
monautrevar = 10;       // Idem avec la valeur entière 10.

background(0);          // Remplit la fenêtre avec le niveau de gris 0 (du noir).
                        // Une valeur de 255 correspond à du blanc.

if(la_condition){       // Les actions situées entre les accolades de cette
                        // structure ne sont effectuées que si la_condition
}                       // est vraie. Si la_condition est fausse, on passe
                        // directement aux actions situées après l'accolade
                        // fermante. Quelques exemples de conditions:
                        // (x<0)        (x<=y)        (x==0)        ((x<0)&&(y>200))

rect(px,py,l,h);        // Dessine un rectangle de point haut gauche de
                        // coordonnées (px,py), de largeur l et de hauteur h.
mouseY                  // Variable prédéfinie contenant la position de la
                        // souris (en nb de pixels, en partant du haut).

fill(255);              // Spécifie la couleur courante de remplissage
                        // (ici du blanc) des objets graphiques.
                        // Cette couleur sera utilisée jusqu'à ce qu'on
                        // appelle à nouveau la fonction fill().

Adapté du poster de l’atelier du LINA (J. Bourdon, É. Languénou).




J.Bourdon et É.Languénou, rédigé par Christophe Gragnic, le 25/02/2017, 16h45'42".






Page générée le 27/05/2021, 09h06'59" (source).
historique de la page
historique global