Javascript : Les boids !

Boids : simuler un essaim d’oiseaux en JavaScript 🐦

Les boids sont une simulation célèbre d’oiseaux (ou de poissons) qui bougent ensemble de manière incroyablement réaliste… avec seulement quelques règles simples ! Ce cours te guide de l’idée jusqu’au code, avec des explications accessibles pour les 11–18 ans et assez poussées pour que les profs et développeurs y reviennent en douce 😏.
Public : ~ 11 → 18 ans Parfait pour illustrer : vecteurs, boucles, comportements émergents

1) Lien de référence : implémentation complète

Nous allons nous inspirer d’une excellente implémentation JavaScript des boids (par Ben Eater) que tu peux consulter ici :

🔗 https://github.com/beneater/boids/blob/master/boids.js

Le fichier complet contient tous les détails de la simulation. Ici, on va comprendre les idées importantes, voir des extraits simplifiés, puis te proposer des pistes d’exercices.

📌 Important : ne recopie pas tout sans comprendre. L’objectif est que tu puisses ensuite écrire ta propre version (plus simple ou plus stylée).

2) Idée générale : des oiseaux très simples, un groupe très intelligent

Dans les boids, chaque “oiseau” (on dit un boid) :

  • a une position (x, y),
  • a une vitesse (vx, vy),
  • ne connaît pas tout le monde, seulement ses voisins proches.

À chaque image (frame) de l’animation, le boid décide comment bouger en appliquant trois grandes règles :

  • Cohésion aller vers le centre du groupe de ses voisins ;
  • Séparation éviter de rentrer dans les autres (ne pas se rentrer dedans) ;
  • Alignement suivre la direction moyenne des voisins.

Ces trois règles sont locales (chaque boid regarde juste autour de lui) mais le comportement global semble “intelligent” et très naturel. C’est un exemple parfait de comportement émergent.

3) Une structure de boid en JavaScript

On peut représenter un boid comme un objet très simple :

// Un boid minimal
const boid = {
  x: 100,   // position x
  y: 150,   // position y
  vx: 2,    // vitesse horizontale
  vy: -1    // vitesse verticale
};

Dans le code complet (voir le lien GitHub), on utilise un tableau de boids :

const boids = [];        // tableau de tous les boids

for (let i = 0; i < 100; i++) {
  boids.push({
    x: Math.random() * width,
    y: Math.random() * height,
    vx: (Math.random() - 0.5) * 2,
    vy: (Math.random() - 0.5) * 2
  });
}
Exercice 1 — créer tes boids
  • Crée une page avec un <canvas> (tu peux réutiliser un de tes modèles précédents).
  • Ajoute un tableau boids et remplis-le avec 50 à 200 boids au hasard.
  • Affiche-les simplement comme des petits disques ou triangles.
Objectif : juste afficher un nuage de boids avant de les faire bouger intelligemment.

4) Mettre les boids en mouvement

Sans règles “intelligentes”, un boid se déplace simplement en ajoutant sa vitesse à sa position à chaque image :

function updateBoid(boid) {
  boid.x += boid.vx;
  boid.y += boid.vy;
}

Et pour toute la “flotte” :

function updateAllBoids() {
  for (const boid of boids) {
    updateBoid(boid);
  }
}
Exercice 2 — première animation
  • Utilise requestAnimationFrame pour appeler en boucle une fonction loop().
  • À chaque frame : efface le canvas, mets à jour la position de chaque boid, puis dessine-les.
  • Gère le “wrap” sur les bords : si un boid sort à droite, il réapparaît à gauche (et pareil haut/bas).
Objectif : avoir une nuée aléatoire qui se balade dans l’écran.

5) Les trois règles fondamentales (version pédagogique)

a) Cohésion — se rapprocher du centre des voisins

Le boid calcule le centre de masse (moyenne des positions) de ses voisins proches, puis ajuste légèrement sa vitesse pour aller dans cette direction.

function ruleCohesion(boid, neighbors) {
  if (neighbors.length === 0) return { dx: 0, dy: 0 };

  let cx = 0, cy = 0;
  for (const other of neighbors) {
    cx += other.x;
    cy += other.y;
  }
  cx /= neighbors.length;
  cy /= neighbors.length;

  // vecteur vers le centre, mais très petit (pour ne pas être trop violent)
  const factor = 0.005;
  return {
    dx: (cx - boid.x) * factor,
    dy: (cy - boid.y) * factor
  };
}

b) Séparation — éviter les collisions

Si un voisin est trop proche, le boid s’en éloigne.

function ruleSeparation(boid, neighbors) {
  let dx = 0, dy = 0;
  const minDist = 20; // distance de sécurité

  for (const other of neighbors) {
    const distX = boid.x - other.x;
    const distY = boid.y - other.y;
    const dist2 = distX * distX + distY * distY;

    if (dist2 < minDist * minDist && dist2 > 0) {
      dx += distX;
      dy += distY;
    }
  }

  const factor = 0.01;
  return { dx: dx * factor, dy: dy * factor };
}

c) Alignement — suivre la direction du groupe

Le boid regarde la vitesse moyenne de ses voisins et rapproche sa propre vitesse de cette moyenne.

function ruleAlignment(boid, neighbors) {
  if (neighbors.length === 0) return { dx: 0, dy: 0 };

  let avgVx = 0, avgVy = 0;
  for (const other of neighbors) {
    avgVx += other.vx;
    avgVy += other.vy;
  }
  avgVx /= neighbors.length;
  avgVy /= neighbors.length;

  const factor = 0.05;
  return {
    dx: (avgVx - boid.vx) * factor,
    dy: (avgVy - boid.vy) * factor
  };
}
Exercice 3 — appliquer les règles
  • Écris une fonction getNeighbors(boid) qui renvoie les boids situés dans un rayon donné.
  • Dans updateBoid(boid), récupère les voisins, applique les 3 règles et additionne les contributions :
function updateBoid(boid) {
  const neighbors = getNeighbors(boid);

  const coh = ruleCohesion(boid, neighbors);
  const sep = ruleSeparation(boid, neighbors);
  const ali = ruleAlignment(boid, neighbors);

  boid.vx += coh.dx + sep.dx + ali.dx;
  boid.vy += coh.dy + sep.dy + ali.dy;

  // option : limiter la vitesse max
  limitSpeed(boid);

  boid.x += boid.vx;
  boid.y += boid.vy;
}

6) Aller voir la version “pro”

Maintenant que tu comprends les concepts, retourne voir le code complet de Ben Eater :

🔗 boids.js sur GitHub

Compare :

  • Comment il calcule les voisins ;
  • Comment il règle les paramètres (forces, distances, vitesse max) ;
  • Comment il dessine les boids (triangles, couleurs, etc.).
🧠 Défi avancé : essaye d’ajouter une quatrième règle dans ta version (par exemple : attraction vers la souris, évitement d’un “prédateur”, etc.).

7) Idées de projets à partir des boids

  • Mode “poissons” : fond bleu, obstacles rochers, un requin qui poursuit l’essaim.
  • Boids musicaux : certains paramètres (distance, vitesse) changent en fonction de la musique.
  • Simulation pédagogique : sliders HTML pour modifier en temps réel la force de cohésion, de séparation, etc.
  • Jeu : le joueur contrôle un boid spécial et doit amener le groupe vers une zone de l’écran.

Mini QCM — Compréhension de l’algorithme des boids

Vérifie que tu as bien saisi les principes avant de te lancer dans ta propre variante.

  1. 1. Le comportement “intelligent” de l’essaim vient principalement :


  2. 2. La règle de séparation sert à :


  3. 3. Dans le code, un boid est typiquement représenté par :


  4. 4. Pourquoi limite-t-on souvent la vitesse maximale d’un boid ?


  5. 5. Dans un code de boids, “neighbors” désigne :


Commentaires

Posts les plus consultés de ce blog

Basthon.fr

mBot2 - programmation mBlock/python

Mario Kart 2D