c’est quoi les boids ?¶
une simulation ludique où on tente de reproduire le comportement d’animaux en
groupes
typiquement nuée d’oiseaux ou banc de poissons
intérêts¶
c’est intéressant parce que
c’est une illustration du modèle de programmation “par acteurs” chaque entité dans l’univers adapte son comportement en fonction de ses voisins immédiats
on y découvre arcade, une autre bibliothèque de jeux pour Python et c’est intéressant pour nous car cette librairie se programme exclusivement par spécialisation de classes
introduction¶
dans ce TP nous allons
découvrir (très superficiellement) la librairie
arcadeet l’utiliser pour implémenter un début de simulation de boids
notre sujet¶
dans sa version originale chaque animal décide de sa trajectoire, en fonction uniquement de ses voisins proches, et cela en suivant trois règles:
séparation (typiquement pour éviter les obstacles)
alignement (tout le monde va, en gros, dans la même direction)
cohésion (rester groupés)
pour la partie imposée de ce TP, on va se contenter d’implémenter la règle de séparation
c’est-à-dire ce qui permet aux boids d’éviter de heurter les autres boids, et les obstacles
les élèves rapides et/ou motivés pourront poursuivre jusqu’à réaliser une simulation complète s’ils le souhaitent
en vidéo¶
voici d’abord une vidéo très courte pour vous montrer les différentes étapes du TP
penser à la lire en plein écran
l’enjeu principal ici est d’être exposé à la programmation par spécialisation de classes
aussi ce chemin par étapes est uniquement indicatif, et surtout à
destination des élèves qui ressentent le besoin d’être guidés pas à pas
si vous vous sentez, vous pouvez très bien vous y prendre complètement autrement !
le contrat est rempli dès que vous avez: des obstacles fixes, et des
boids qui évoluent spontanément en évitant les obstacles et les autres
boids
contenu du zip¶
le zip contient
le starter code dans
boids-02.pyles figures dans le dossier
media/
pas à pas¶
v02: starter code¶
dans le zip vous trouverez le code suivant; n’hésitez pas à le renommer dans un fichier
boids.pysi vous préférez
le code de départ
"""
simplest possible starting code with one motionless boid
display a single object, inert, at (100, 100)
with arcade-3.x this is the starter step, and
Window has a self.boids instead of a single self.boid
"""
import arcade
BACKGROUND = arcade.color.ALMOND
IMAGE = "media/arrow-resized.png"
class Window(arcade.Window):
def __init__(self):
super().__init__(800, 800, "My first boid")
arcade.set_background_color(BACKGROUND)
self.set_location(800, 100)
self.boids = None
def setup(self):
boid = arcade.Sprite(IMAGE)
boid.center_x = 100
boid.center_y = 100
self.boids = arcade.SpriteList()
self.boids.append(boid)
def on_draw(self):
self.clear()
self.boids.draw()
def on_update(self, delta_time):
self.boids.update()
window = Window()
window.setup()
arcade.run()
installez la librairie (comment fait-on déjà ?)
vérifiez que vous avez le fichier
media/arrow-resized.png(il est dans le zip)lancez le code ci-dessus
vous devez voir un seul boid immobile, dans le coin en bas à gauche
v03: le boid avance¶
maintenant on va faire bouger notre objet, et lui donner un mouvement rectiligne
et pour ça on va cesser d’utiliser directement la classe Sprite,
et on va au contraire la spécialiser pour créer notre propre classe Boid
(c-à-d que la classe Boid hérite de la classe Sprite)
v04: en circuit fermé¶
on va faire en sorte que le plateau devienne infini en le refermant sur lui-même
i.e. un objet sortant à gauche réapparait à droite, et idem dans tous les sens…ça peut valoir le coup de “sortir” la taille du jeu pour en faire des constantes
et pour que ce soit plus facile à tester on va orienter le boid vers le coin en bas à gauche
si vous vous y êtes bien pris pour le faire avancer, c’est juste une question de changer son.angle
v05: du bruit sur le cap¶
faites en sorte que le trajet du boid ne soit plus strictement rectiligne
en ajoutant à chaque pas un léger bruit sur la direction
v06: les touches ← et →¶
faites en sorte de pouvoir contrôler la direction du boid avec les touches du clavier
v07: ajouter un obstacle¶
ajoutez un unique obstacle, immobile, par exemple au centre du jeu
vous trouverez une image media/obstacle-resized.png pour le matérialiser
v08: créez une grille d’obstacles¶
remplacez l’unique obstacle par une grille d’obstacles
par exemple: mettez en 10 x 10, ils sont donc espacés de 80px
v09: détecter les voisins¶
faites en sorte d’animer le boid, pour montrer quand il est proche d’un obstacle ou pas
prenez 20 pixels comme rayon de détection
pour ma part j’ai rendu le boid semi-transparent, en jouant sur l’attribut alpha des Sprite
(255 = opaque, 0 = transparent)
v10: la règle de séparation¶
implémentez la règle de séparation
on peut la résumer comme ceci:

c’est-à-dire que quand on s’intéresse au boid b, on va
ignorer tous les objets (en rouge) qui se trouvent plus loin qu’un certain rayon ‘r’
et pour tous ceux qui sont proches (en vert), par exemple o, on calcule un vecteur qui va permettre d’écarter l’objet b de o
je n’ai pas trouvé de formule dans la littérature pour calculer , j’ai sorti de mon chapeau la formule suivante
de façon à ce que:
les objets sur le cercle ont une influence nulle,
et si o est tout proche de b, il est repoussé à un rayon r/2
on fait la somme de tous ces vecteurs, et on l’ajoute au déplacement de b
i.e., dans l’exemple de la figure, lorsqu’on traite le boid en b:
on ignore les boids éloignés - en rouge
et pour les 3 boids proches - en vert - on fait la somme des 3 vecteurs de “repoussement” (en vert aussi)
qu’on ajoute naturellement au déplacement dû à la vitesse du boid
v11: orienter correctement¶
dans cette version, on va essayer de répercuter les collisions sur l’orientation du boid
et pour ça on va mettre à jour brutalement l’attribut
angleà ce stade, on se base uniquement sur le mouvement qui est fait à l’instant t:
pour être explicite, si on passe de (x1, y1) à (x2, y2), on oriente le boid pour s’aligner sur le vecteur (x2-x1, y2-y1)
l’effet n’est pas forcément très réussi, vous devez voir l’orientation sauter brutalement d’un angle à un autre
v12: tourner plus doucement¶
pour lisser les changements d’orientation: comment pourrait-on obtenir quelque chose d’un peu plus élégant, en ce qui concerne les changements de direction ?
v13: les touches ↑ et ↓¶
faire en sorte qu’on puisse contrôler aussi la vitesse avec les touches ↑ et ↓
essayez le comportement de l’évitement d’obstacles à plusieurs vitesses
v14: plusieurs boids¶
remplacez l’unique boid par un ensemble de 20 boids
sans changer, pour l’instant, la séparation, qui est calculée seulement à partir des obstacles
v15: éviter aussi les autres boids¶
assurez-vous que la séparation permet d’éviter tous les objets (obstacles et boids)
en option...¶
vous pouvez ensuite améliorer dans les directions suivantes :
implémenter les deux autres règles (alignement et cohésion)
faire en sorte qu’on puisse interactivement ajouter/enlever des obstacles
faire des raccourcis clavier pour activer/désactiver les 3 règles, et le bruit
bien tenir compte de la vitesse de rafraichissement du jeu
i.e., est-ce que la simulation continue de fonctionner si on ralentit la logique du jeu avecWindow.set_update_rate()etc...
pour information voici une synthèse des 3 règles, à vous de chercher pour préciser comment interpréter ces figures

pour aller plus loin¶
pour plus de détails sur les boids, voir la page de Craig Reynolds, l’auteur original
je vous signale un tutoriel intéressant sur la librairie arcade assez long / exhaustif
enfin d’autres vidéos qui peuvent vous inspirer également (parmi autres) :