A › 9 - Fonctions

Les fonctions permettent d'éviter les répétitions d'instructions dans un programme, afin d'en faciliter la lecture et d'éventuelles mises à jour. Les instructions qui se répètent sont isolées dans un bloc, placé après la fonction draw(). On associe un nom à ce bloc d'instructions, ce qui permet d'appeler cette fonction depuis toute autre partie du programme.

A chaque appel de la fonction, les intructions comprises dans le corps de la fonction sont exécutées.

Deux instructions distinctes sont nécessaires pour créer et utiliser une fonction : la définition de la fonction et l'appel de la fonction.

Premiers exemples : fonctions sans paramètre

Une fonction peut soit "retourner" une valeur d'un type fixé, à l'aide du mot-clef return, soit ne pas "retourner" de valeur, mais effectuer un tracé, un affichage, ou une action qui n'est pas directement visible à l'écran. Ces dernières fonctions sont définies à l'aide du mot-clef void.

Exemples :

  • Exemple 1 : Un jeu comportant un ou plusieurs joueurs se joue avec deux dés. A chaque coup, un joueur "lance" deux dés et la somme des deux dés est prise en compte dans la progression dans le jeu. On crée une fonction pour simuler le lancer des deux dés, qui sera utilisée de nombreuses fois au cours du jeu.

    Etape 1 : définition d'une fonction qui renvoie la somme de deux dés.

    int lancerDeuxDes() // cette fonction, nommée lancerDeuxDes(), devra renvoyer une valeur entière (type int).

    {

      int lancer1=floor(random(1,7));// lancer1 est un entier aléatoire entre 1 et 6

      int lancer2=floor(random(1,7));// lancer2 est un entier aléatoire entre 1 et 6

      return(lancer1+lancer2);// la fonction lancerDeuxDes() renvoie la somme de lancer1 et lancer2

    }

    Etape 2 : appel de la fonction

    A l'intérieur du programme, on appelle la fonction lancerDeuxDes() à chaque fois qu'il est nécessaire, en prenant en compte le fait que cette fonction renvoie un entier, par exemple :

    int scoreJoueur1=lancerDeuxDes();// scoreJoueur1 sera la somme de deux lancers de dés


  • Exemple 2 : Une animation graphique fait apparaître des "bulles aléatoires" dont le diametre et les coordonnées sont des nombres aléatoires. On crée une fonction pour tracer chaque bulle.

    Etape 1 : définition d'une fonction qui trace une "bulle".

    void bulle() // cette fonction, nommée bulle(), ne renverra aucune valeur (mot-clef : void).

    {

      int diametre=floor(random(1,15));// diametre est un entier aléatoire entre 1 et 14

      int x=floor(random(1,width));// x est une abscisse aléatoire

      int y=floor(random(1,height));// y est une ordonnée aléatoire

      ellipse(x,y,diametre,diametre);// la fonction bulle() effectue un tracé à l'écran

    }

    Etape 2 : appel de la fonction

    A l'intérieur du programme, on appelle la fonction bulle() dans la fonction draw(), qui est donc répétée en boucle indéfiniment, par l'instruction :

    bulle();// oui, c'est tout...

    Que donne le programme complet ?

void setup(){

  size(200,200);

  frameRate(10); // 10 dessins par seconde

  noStroke(); // tracé de contour désactivé

}

void draw(){

  fill(0,120,240,10); // remplisage bleu, avec transparence

  rect(0,0,width, height); // on recouvre la fenêtre avec une couche transparente

  fill(255); // couleur des bulles

  bulle(); // appel de la fonction bulle()

}

void bulle() // définition de la fonction.

{

  int rayon=floor(random(1,15));// rayon est un entier aléatoire entre 1 et 14

  int x=floor(random(1,width));// x est une abcscisse aléatoire

  int y=floor(random(1,height));// y est une ordonnée aléatoire

  ellipse(x,y,rayon,rayon);// la fonction bulle() effectue un tracé à l'écran

}

Fonctions avec paramètre(s)

Pour s'exécuter, une fonction peut nécessiter des informations, des valeurs de variable(s) qu'il faut lui transmettre lors de l'appel de la fonction. On appelle ces données les paramètres de la fonction. Ils sont explicitement décrits avec leur type lors de la définition de la fonction.

A nouveau ces fonctions peuvent, comme celles sans paramètre(s), soit "retourner" une valeur d'un type fixé à l'aide du mot-clef return, soit ne pas "retourner" de valeur, mais effectuer un tracé, un affichage, ou une action qui n'est pas directement visible à l'écran.

Exemples :

  • Exemple 3 : Lorsqu'on souhaite tracer un cercle dont le diamètre est donné par deux points, il faut pouvoir calculer la distance entre ces deux points. On peut créer une fonction pour cela, qui utilise la formule de la distance dans un repère orthonormé (vue en 2nde). Le résultat renvoyé sera un nombre décimal donc la fonction sera de type float.

    Etape 1 : définition d'une fonction qui calcule la distance entre les points de coordonnées (x1,y1) et (x2,y2).

    float distance (float x1, float y1, float x2, float y2);// distance() dépend des coordonnées des points

    {

      return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));// sqrt=racine carrée

    }

    Etape 2 : appel de la fonction

    A l'intérieur du programme, on appelle la fonction distance() à chaque fois qu'il est nécessaire, en prenant en compte le fait que cette fonction renvoie un décimal, par exemple :

    float d=distance(valeur de x1, valeur de y1, valeur de x2, valeur de y2);// chaque valeur est soit un nombre (du type float), soit une variable (du type float) dont la valeur est connue lors de l'appel de la fonction.

    Voici un programme qui utilise cette fonction :

float x1, x2, pas;

diam=70; // diamètre des boules rouges

void setup(){

  size(200,200);

  x1=40;// abscisse initiale du centre de la boule du haut

  pas=0.4;

}

void draw(){

  fill(255,20); // transparence pour laisser trace des mouvements

  rect(0, 0, width, height);

  stroke(220, 10, 30); // tracé rouge

  fill(255);

  line(0, 50, 200, 50);

  line(0, 150, 200, 150);

  x2=width-x1;

  ellipse(x1, 50, diam, diam);

  ellipse(x2, 150, diam, diam);

  line(x1, 50, x2, 150);

  float d = distance(x1, 50, x2, 150) - diam ;// appel de la fonction distance

  stroke(20, 10, 230);// bleu

  ellipse((x1+x2)/2, height/2, d, d);

  x1=x1+pas;

  if ((x1 > width-diam/2)||(x1 < diam/2)) { // si la boule du haut "touche" les parois

    pas=-pas; // on change la direction des boules rouges

  }

}

float distance (float x1, float y1, float x2, float y2);// définition de la fonction distance()

{

  return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));// sqrt=racine carrée

}

  • Exemple 4 : Une animation graphique fait apparaître des polygones réguliers dont le nombre de côtés, les dimensions et la position peuvent varier. On crée une fonction pour tracer chaque polygone, dépendant de tous les paramètres.

    Etape 1 : définition d'une fonction qui trace un polygone.

    void polygone(float x, float y, float rayon, int nbPoints) // cette fonction, nommée polygone(), ne renverra aucune valeur (mot-clef : void). Elle dépend de 4 paramètres : 3 sont des décimaux (float) et nbPoints est un entier.

    {

      float angle = TWO_PI / nbPoints;

      float px=x+rayon;// px est l'abcscisse du sommet initial

      float py=y;// py est l'ordonnée du sommet initial

      for (int k = 1; k <=nbPoints; k=k+1) {

        float sx = x + cos(k*angle) * rayon; // abscisse du k-ième point

        float sy = y + sin(k*angle) * rayon; // ordonnée du k-ième point

        line(px,py,sx,sy);// segment reliant le k-ième point au précédent

        px=sx;

        py=sy;

      }

    }

    Etape 2 : appel de la fonction

    A l'intérieur du programme, on appelle la fonction polygone() dans la fonction draw(), en précisant la valeur que prend chaque paramètre à l'aide de l'instruction :

    polygone(valeur de x, valeur de y, valeur du rayon, nombre de sommets);// chaque valeur est soit un nombre (du bon type, float ou int), soit une variable (du bon type, float ou int) dont la valeur est connue lors de l'appel de la fonction.

    Voici un programme complet qui utilise trois fois cette fonction dans le draw():

float decalage = 0.0;

void setup(){

  size(200,200);

  strokeWeight(5); // épaisseur de tracé : 5 pixels

}

void draw(){

  background(255); // fond blanc

  stroke(80,140,250); // tracé bleu

  polygone(100, 100, 80, 8); // octogone : x=100, y=100, rayon=80, nbPoints=8

  stroke(220,10,30); // tracé rouge

  polygone(70, 120, 30, 4); // carré : x=70, y=120, rayon=30, nbPoints=4

  stroke(20, 210,50); // tracé vert

  polygone(190-decalage, 70, 20, 5); // pentagone, mobile : x=190-decalage, y=70, rayon=20, nbPoints=5

  decalage=decalage+0.3; // paramètre qui permet de décaler le pentagone

}

void polygone(float x, float y, float rayon, int nbPoints)// définition de la fonction

{

  float angle = TWO_PI / nbPoints;

  float px=x+rayon;// px est l'abcscisse du sommet initial

  float py=y;// py est l'ordonnée du sommet initial

  for (int k = 1; k <=nbPoints; k=k+1) {

    float sx = x + cos(k*angle) * rayon; // abscisse du k-ième point

    float sy = y + sin(k*angle) * rayon; // ordonnée du k-ième point

    line(px,py,sx,sy);// segment reliant le k-ième point au précédent

    px=sx;

    py=sy;

  }

}