Table des matières

Bille qui rebondit

Lorsque l'on fait des animations, on doit souvent prévoir des comportement qui semblent physiquement acceptables :

Nous allons suivre ici l'exemple d'une bille qui rebondit.

Dans un premier temps, nous n'utiliserons pas de classe. Dans un deuxième temps nous ajouterons une classe pour permettre l'étape suivante : beaucoup de billes qui rebondissent.

Physique de base

Notre bille sera un cercle d'un certain diamètre taille d, une certaine position x, y. À chaque instant la bille tombera verticalement avec une vitesse vy. L'accélération de la pesanteur g modifiera la valeur de vy. Enfin, la bille rebondira sur la ligne du bas de la fenêtre mais en perdant un peu de vitesse. On notera r le facteur de proportionnalité entre la vitesse avant le choc et la vitesse après le choc. On a bien sûr 0 < r <= 1.

  • y grandit vers le bas. Le sol est atteint quand on touche le bord inférieur de la fenêtre. On peut connaître la hauteur de la fenêtre grâce au mot-clé height. Idem pour la largeur avec width.
  • on ne choisit pas pour g la valeur physique de $9,81\,m\cdot s^{-2}$ car il faudrait alors faire une conversion prenant en compte l'unité de longueur sur l'écran et l'unité de temps de l'animation. Même si on mène ces calculs à bien, il n'est pas évident que l'animation en soit plus satisfaisante. Il est bien plus efficace de choisir, après quelques essais, la valeur qui produit l'animation la plus esthétique.

Si y > height, cela signifie que la bille a dépassé le bord du bas et qu'elle doit donc rebondir.

Le script

final float g = 0.05;
final float r = 0.8;
int d; // diamètre bille
float x, y, vy;

void setup() {
  size(600, 400);
  x = 300;
  y = 10;
  vy = 0;
  d = 5;
}

void draw() {
  background(250); // en niveau de gris
  vy += g;
  y += vy;
  if (y > height) {
    // rebond
    float depassement = y - height;
    y = height - r*depassement;
    vy = -r*vy;
  }
  circle(x, y, d);
  
}

Avec un objet

On peut confier la physique à la bille elle-même ce qui permettra de multiplier les billes sans alourdir le code.

final float g = 0.05;
final float r = 0.8;

Bille b;

void setup() {
  size(600, 400);
  b = new Bille(300, 10, 5);
}

void draw() {
  background(250); // en niveau de gris
  b.update();
  b.display();
}

class Bille {
  float x, y, vy, d;
  Bille(float x0, float y0, float d0) {
    d = d0;
    x = x0;
    y = y0;
    vy = 0;
  }
  
  void update() {
      vy += g;
      y += vy;
      if (y > height) {
        // rebond
        float depassement = y - height;
        y = height - r*depassement;
        vy = -r*vy;
      }
  }
  
  void display() {
    circle(x, y, d);
  }
}