Programme de base

Pour toute cette partie, vous pourrez réutilise le code suivant qui correspond à l'une des corrections possible du chapitre "Et maintenant, ils sont plusieurs"

from  p5 import *
from random import uniform

largeur,hauteur = 500, 500
abscisse, ordonnee, rayon = [],[],[]
vitesseX, vitesseY = [],[]
nbBlobs = 12

def setup():
    global abscisse, ordonnee, rayon, vitesseX, vitesseY
    size(largeur,hauteur)
    for _ in range(nbBlobs) :
        abscisse.append(uniform(0,largeur))
        ordonnee.append(uniform(0,hauteur))
        rayon.append(uniform(15,30))
        vx = uniform(-5,5)
        vy = uniform(-5,5)
        if vx == 0 and vy == 0:
            vx = 1
        vitesseX.append(vx)
        vitesseY.append(vy)

def draw():
    global abscisse, ordonnee, vitesseX, vitesseY
    background(0)
    for i in range(nbBlobs) :
        circle(abscisse[i],ordonnee[i],rayon[i])
        abscisse[i] += vitesseX[i]
        ordonnee[i] += vitesseY[i]
        if abscisse[i] > largeur :
            abscisse[i] = largeur
            vitesseX[i] = - vitesseX[i]
        if abscisse[i] < 0 :
            abscisse[i] = 0
            vitesseX[i] = -vitesseX[i]
        if ordonnee[i] > hauteur :
            ordonnee[i] = hauteur
            vitesseY[i] = -vitesseY[i]
        if ordonnee[i] < 0 :
            ordonnee[i] = 0 
            vitesseY[i] = - vitesseY[i]

run()

Le fond pour nos formes.

Jusqu'ici vos algoblobs avaient évolués sur un fond noir systématique. Vous activiez ce fond en utilisant la commande background(0). Il y aurait sans doute moyen de faire un autre fond.

Nous allons ici proposer trois fond différents pour nos algoblobs :

Mettre les formes pour s'occuper du fond

Avant de nous ruer sur le code informatique dans un éditeur, nous allons nous poser et réfléchir un peu à la façon dont nos nos diverses situations s'expriment en terme informatique. Dans le type de programmation impératif (et objet) que nous avons utilisé jusqu'ici, des actions seront associées à des fonctions. Nous allons commencer par exprimer clairement pour chacune de nos fonctions

fonction paramètres définition
fond_uni couleur fond_uni('yellow')
la couleur est une couleur au sens de p5 (une chaine de caractère, un triplet RGB ou une valeur en notation hexadécimale). Le fond sera dans cette couleur
fond_degrade triplet1,triplet2 fond_degrade((255,255,255),(128,200,230))
Le fond sera fait sur un dégradé vertical de couleur. En haut de la fenêtre, la couleur sera celle définir par le premier triple RGB (dans l'exemple, du blanc défini par 255 trois fois), en bas de la fenêtre, ce sera la couleur définie par le second triple RGB (ici, une couleur bleu claire)
fond_damier largeur,hauteur,triplet1,triplet2 fond_damier(25,25,(128,128,128),(0,0,0))
fait un fond sous forme de damier. Les deux premiers argument indique la largeur et la hauteur de chaque case du damier. Les deux suivant sont les triplets de couleurs qui correspondent aux couleurs des cases (dans notre exemple, des cases gris moyen et noires). La première case de la première ligne sera de la couleur du premier triplet

Ce que nous venons de faire, c'est de donner les spécifications de nos fonctions.

Implémenter

Lorsque les spécifications sont faîtes, il faut ensuite réaliser un code qui correspond à cette spécification. On dit que l'on implémente le code. Il faut être conscient que pour une spécification donnée, il peut y avoir plusieurs implémentations différentes. Certaines seront équivalentes, certaines seront plus efficaces, certaines seront plus élégantes, d'autres plus maintenables. La seule chose importante, c'est que l'implémentation corresponde à la spécification.

  • Spécifier, c'est indiquer précisément pour une fonction (ou une classe, ou un module) quels sont les paramètres à fournir et quel est le résultat attendu
  • Implémenter une spécification, c'est réaliser le code qui correspond à notre spécification.
Exemple de la fonction fond_uni

La fonction fond_uni est très simple à réaliser

def fond_uni(col):
    background(col)

Il est intéressant lorsque l'on réalise une fonction d'y intégrer la documentation. De ce point de vue là, le langage Python permet nativement d'intégrer la documentation dans la fonction ! C'est plus facile. En gros, il suffit de mettre une chaîne de caractères au début de la fonction. Cela s'appelle les docstrings. On peut même inclure des tests à l'intérieur de Docstrings. Le plus simple est de consulter le tutoriel de Sam & Max sur le sujet ( NB : l'écoute de la musique est totalement facultatif )

  • Consultez la documentation ci dessus
  • Réalisez la documentation de votre fonction fond_uni

Réalisation

Vous allez maintenant réaliser les deux fonctions qui sont à faire pour changer le fond : la fonction qui fait un fond dégradé et la fonction qui fait un damier. Pour le fond dégradé, vous pouvez utiliser une petite fonction utilitaire de p5 : la fonction remap. Cette fonction permet de retranscrire une valeur d'un intervalle vers un autre. Ce n'est ni plus ni moins une fonction affine. Par exemple le code suivant :

remap(25,(0,100),(0,1))
donnera pour résultat 0.25 (il remplace les valeurs entre 0 et 100 par des valeurs entre 0 et 1). Vous pourriez le faire vous même, mais cela vous aidera peut être.

Pour la fonction dégradé, nous aurons à tracer des traits en utilisant la fonction line (qui prend quatre paramètres : x1,y1,x2,y2 qui sont les abscisses et les ordonnées des extrémités du segment). Ces lignes auront des ordonnées qui iront de 0 à hauteur. Nous couleurs elles aussi devront varier de la couleur de départ à la couleur d'arrivée. On pourra utiliser remap.

Écrivez le code des deux fonctions fond_degrade et fond_damier. N'oubliez pas de documenter le code

C'est fait ? Félicitez vous, vous allez pouvoir offrir le fond qu'ils méritent aux algoblobs

un fond de votre cru
Faites vous plaisir en concevant une fonction qui fabrique un fond qui vous corresponde. Soyez créatif !

Modularité

Nos fonctions pour créer et animer des fonds sont très bien. Du coup, nous allons vouloir les utiliser pour tout un tas de programmes autour de nos algoblobs. Il serait regrettable de devoir faire des copier coller de ces fonctions à chaque fois. Nous voudrions pouvoir les déposer dans un fichier à part que nous utiliserions à chaque fois.

En fait, vous faîtes déjà cela depuis un moment !

Lorsque par exemple vous utiliser des fonctions pour utiliser les nombres aléatoires, vous utiliser un ensemble de fonction qui ont été regroupé dans un module. Ce module standard s'appelle random et les fonctions ont été placées dans le fichier random.py

  • Placez vos fonctions dans un fichier fonds.py
  • Rajoutez une ligne import fonds au début de votre fichier principal
  • Utiliser les fonctions de votre module en n'oubliant pas de mettre le prefixe ( fonds.fond_uni('red') par exemple )
  • Documentez votre module. Vous pouvez relire le tutoriel de Sam & Max sur le sujet
  • Vous pouvez utiliser des évènement pour modifier le comportement du fond. Essayer de faire en sorte que lorsque l'on appuie sur certaines touches (vous choisissez les lettres), les fonds changent. Vous pouvez revoir la partie sur les évènements. Vous pouvez en particulier utiliser la fonction key_typed

Voici un exemple de réalisation en javascript.