import p5
from random import randint
# liste des couleurs possibles
couleurs = ['white', 'red', 'green', 'blue', 'cyan', 'yellow', 'magenta']
# fonction de mise en place
def setup():
p5.createCanvas(600, 400)
# fonction d'animation
def draw():
global x, y, couleur, taille, vitesse
# 1. Effacement global de la fenêtre :
p5.background(0)
# 2 . Déplacement de la bulle vers le haut en tenant compte de sa vitesse;
# Quand la bulle arrive en haut de la fenêtre, on réinitialise ses caractéristiques.
y = y - vitesse # ou y -= vitesse
if y <= 0:
y = p5.height
x = randint(10,590)
couleur = randint(0,6)
taille = randint(10,20)
vitesse = randint(15,20)
# 3. Dessin de la bulle dans la fenêtre :
p5.fill(couleurs[couleur])
p5.ellipse(x, y, taille)
# initialisation des caractéristiques de la bulle
x = randint(10,590)
y = p5.height
couleur = randint(0,6)
taille = randint(10,20)
vitesse = randint(15,20)
p5.run(setup, draw)
Deux choses pour gérer le mouvement de la bulle :
draw
), modifier l'ordonnée y de la bulle pour faire "monter" cette dernière : il faut donc décrémenter la variable y ( ligne 21 ).y <= 0
, c'est à dire si la bulle "sort" de l'écran par le haut, et, dans ce cas, réinitialiser les caractéristiques la bulle.Une remarque sur la condition à tester pour "savoir" si la bulle atteint le sommet : on ne peut pas utiliser une simple égalité, car, selon la valeur de la variable vitesse, la variable y n'obtiendra peut-être jamais la valeur 0; il faut donc tester une inégalité qui, elle, sera forcément vérifiée à un moment ou un autre, quelle que soit la valeur de vitesse.
Facile : on recopie les variables et les instructions pour gérer le mouvement de la bulle, et on les réutilise avec de nouveaux noms :
import p5
from random import randint
# liste des couleurs possibles
couleurs = ['white', 'red', 'green', 'blue', 'cyan', 'yellow', 'magenta']
# fonction de mise en place
def setup():
p5.createCanvas(600, 400)
# fonction d'animation
def draw():
global x, y, couleur, taille, vitesse
global x2, y2, couleur2, taille2, vitesse2
# 1. Effacement global de la fenêtre :
p5.background(0)
# 2 . Déplacement des bulles
y = y - vitesse
y2 = y2 - vitesse2
if y <= 0:
y = p5.height
x = randint(10,590)
couleur = randint(0,6)
taille = randint(10,20)
vitesse = randint(15,20)
if y2 <= 0:
y2 = p5.height
x2 = randint(10,590)
couleur2 = randint(0,6)
taille2 = randint(10,20)
vitesse2 = randint(15,20)
# 3. Dessin des bulles dans la fenêtre :
p5.fill(couleurs[couleur])
p5.ellipse(x, y, taille)
p5.fill(couleurs[couleur2])
p5.ellipse(x2, y2, taille2)
# initialisation des caractéristiques des bulles
x = randint(10,590)
y = p5.height
couleur = randint(0,6)
taille = randint(10,20)
vitesse = randint(15,20)
x2 = randint(10,590)
y2 = p5.height
couleur2 = randint(0,6)
taille2 = randint(10,20)
vitesse2 = randint(15,20)
p5.run(setup, draw)
Argh....
Cette façon d'envisager le programme devient de plus en plus délicate à gérer :
D'où la nécessité de passer, dans cette situation, à une autre façon de concevoir le programme, un autre paradigme de programmation, la Programmation Orientée Objet ( POO ).
En réfléchissant bien au problème, on pouvait tout de même remplacer toutes ces variables par les éléments d'un tableau de tableaux, chaque sous-tableau codant une bulle; en parcourant ce tableau, on peut alors s'adresser à chaque bulle sans avoir besoin de préciser de nom de variables :
import p5
from random import randint
# liste des couleurs possibles
couleurs = ['white', 'red', 'green', 'blue', 'cyan', 'yellow', 'magenta']
# fonction de mise en place
def setup():
p5.createCanvas(600, 400)
# fonction d'animation
def draw():
# 1. Effacement global de la fenêtre :
p5.background(0)
# 2 . Déplacement de la bulle vers le haut en tenant compte de sa vitesse;
for bulle in tab: # parcours du tableau des bulles
bulle[1] -= bulle[4]
# Quand la bulle arrive en haut de la fenêtre, on réinitialise ses caractéristiques.
if bulle[1] < 0:
bulle[0] = randint(10,590)
bulle[1] = p5.height
bulle[2] = randint(0,6)
bulle[3] = randint(10,30)
bulle[4] = randint(5,15)
# 3. Dessin de la bulle dans la fenêtre :
p5.fill(couleurs[bulle[2]])
p5.ellipse(bulle[0], bulle[1], bulle[3])
# initialisation des caractéristiques des bulles
tab = [] # tableau des bulles
for i in range(50):
tab_bulle = [] # tableau qui représente une bulle
x = randint(10, 590)
y = p5.height
couleur = randint(0, 6)
taille = randint(10, 30)
vitesse = randint(5, 15)
tab_bulle = [x, y, couleur, taille, vitesse]
tab.append(tab_bulle)
p5.run(setup, draw)
En plus, plus besoin de global
, un tableau est déjà global à un script ( cf. cours de Première ) !
Bulle
class Bulle:
# constructeur
def __init__(self,x, y, couleur, taille, vitesse):
self.x = x
self.y = y
self.couleur = couleur # indice de la couleur dans la liste 'couleurs'
self.taille = taille
self.vitesse = vitesse
def affiche(self):
couleurs = ['white', 'black', 'red', 'green', 'blue', 'cyan', 'yellow', 'magenta']
p5.fill(couleurs[self.couleur])
p5.ellipse(self.x, self.y, self.taille)
def monte(self):
if y <= 0:
self.y = p5.height
self.x = randint(10,590)
self.couleur = randint(0,6)
self.taille = randint(10,20)
self.vitesse = randint(15,20)
Pour chaque méthode ou attribut d'un objet, il faut préfixer son nom par self.
Par contre, la liste couleurs ( attention, pas l'attribut self.couleur ! ) est commune à tous les objets : on n'a donc pas besoin de la préfixer par self.
, ce sera la même pour tous les objets.
import p5
...
class Bulle:
...
# fonction de mise en place
def setup():
p5.createCanvas(600, 400)
# fonction d'animation
def draw():
p5.background(0) # effacement de la bulle
bulle1.monter() # déplacement
bulle1.afficher() # affichage
# instanciation d'un objet de type "Bulle"
x = randint(10,290)
y = p5.height
couleur = randint(0,7)
taille = randint(2,10)
vitesse = randint(1,10)
bulle1 = Bulle(x, y, couleur, taille, vitesse) # arguments dans le même ordre que les paramètres du constructeur
p5.run(setup, draw)
Bulle
est créé; pour le désigner, on lui associe un nom de variable ( ici : bulle1 ).draw
, on utilise alors les méthodes monter
et afficher
associée à l'objet, en utilisant la syntaxe présentée dans le cours.Dans le programme principal, on crée une liste dont chaque élément sera un objet :
# instanciation des objets de type "Bulle"
bulles = [] # tableau d'objets de type 'Bulle'
for i in range(50): # 50 bulles
x = randint(10,290)
y = 190
couleur = randint(0,7)
taille = randint(2,10)
vitesse = randint(1,10)
bulle = Bulle(x, y, couleur, taille, vitesse) # création de l'objet
bulles.append(bulle) # ajout comme élément du tableau 'bulles'
p5.run(setup, draw)
Dans la fonction draw
, on parcourt la liste d'objets, en appelant, pour chacun de ces éléments ( qui sont des objets de type Bulle ) leurs méthodes monter
et afficher
:
# fonction d'animation
def draw():
p5.background(0) # effacement de la bulle
for bulle in bulles: # parcours par valeur du tableau des bulles
bulle.monter() # déplacement
bulle.afficher() # affichage
Le code complet du script est ici.
La méthode importante est la méthode rebonds
: elle prend comme paramètre un autre objet de type Balle
:
class Balle:
....
def rebonds(self, autre_balle): # le constructeur prend comme paramètre un AUTRE objet de type 'Balle'
dx = autre_balle.x - self.x
dy = autre_balle.y - self.y
distance = sqrt(dx**2 + dy**2)
minDist = autre_balle.taille//2 + self.taille//2
if (distance < minDist):
self.vx = -self.vx
self.vy = -self.vy
autre_balle.vx = -autre_balle.vx
autre_balle.vy = -autre_balle.vy
Et cette méthode doit être appelée dans la fonction draw
pour chacun des balles successivement :
def draw():
# Effacement de la fenêtre
p5.background(0)
# Traitement de la première balle
balle1.move() # déplacement
balle1.rebonds(balle2) # appel de la méthode 'rebonds' depuis l'objet 'balle1' avec comme argument l'objet 'balle2'
balle1.affiche() # affichage
# Traitement de la deuxième balle
balle2.move()
balle2.rebonds(balle1) # # appel de la méthode 'rebonds' depuis l'objet 'balle2' avec comme argument l'objet 'balle1'
balle2.affiche()
Le code complet du script est ici.
Le code complet du script est ici.
Le code complet du script est ici.