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.
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
});
}
- Crée une page avec un <canvas> (tu peux réutiliser un de tes modèles précédents).
- Ajoute un tableau
boidset remplis-le avec 50 à 200 boids au hasard. - Affiche-les simplement comme des petits disques ou triangles.
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);
}
}
- Utilise
requestAnimationFramepour appeler en boucle une fonctionloop(). - À 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).
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
};
}
- É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 :
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.).
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.
Commentaires
Enregistrer un commentaire