1ère Partie : Animation simple d’une balle sur un canvas.

 

***********************************************
'''
Created on 23 août 2016

@author: vfsilesieux
'''
from random import randint#on importe la fonction randint du module random qui génère des nombres entiers aléatoires
x,y=150,10#les positions initiales de la balle
dx,dy=10,10#les valeurs des déplacements horizontaux et verticaux de la balle
flag=0#une variable qui vaut 0 lorsque la balle est à l'arrêt, et mise à 1 autrement
def start():#la fonction qui déclenche le déplacement
    global flag,dx,dy#on précise que ces variables sont globales
    dx,dy,flag=randint(-11,11),randint(-11,11),1#on affecte une valeur aléatoire aux déplacements
    move()#on lance le déplacement
def stop():
    global dx,dy,flag
    dx,dy,flag=0,0,0#on arrête la balle
def move():
    global x,y,dx,dy
    x,y=x+dx,y+dy#la balle se déplace
    if x>240:#la balle rebondit si elle frappe le bord droit (240=250-rayon de la balle)
        dx=-dx
    if x<10:#la balle rebondit si elle frappe le bord gauche (10=rayon de la balle)
        dx=-dx
    if y<10:#la balle rebondit si elle frappe le bord supérieur (10=rayon de la balle)
        dy=-dy
    if y>240:#la balle rebondit si elle frappe le bord inférieur (240=250-rayon de la balle)
        dy=-dy
    can.coords(oval,x,y,x+10,y+10)#on dessine la balle sur le canvas 
    if flag==1:        
        fenetre.after(50,move)#on déplace la balle toutes les 50 ms
from tkinter import *#on importe le module tkinter
fenetre = Tk()#on donne un nom à la fenêtre
fenetre.geometry("350x300")#on choisit la taille de la fenêtre
can = Canvas(fenetre,bg="dark grey",height=250, width=250)#on choisit les dimensions du canvas et la couleur du background
can.pack(side=LEFT,padx=5,pady=5)#on positionne le canvas sur la fenêtre
oval=can.create_oval(x,y,x+10,y+10,width=2,fill="red")#on dessinne une balle sur le canvas
boutonGO = Button(fenetre, text="GO", width =3, command=start)#on crée un bouton Go qui lance la fonction start()
boutonGO.pack(side=BOTTOM)#on place le bouton en bas sur la fenêtre
boutonSTOP = Button(fenetre, text="STOP", width =3, command=stop)#on crée un bouton Stop qui arrête le déplacement de la balle
boutonSTOP.pack(side=BOTTOM)#on place le bouton en bas sur la fenêtre
fenetre.mainloop()#on place un gestionnaire d'événements sur la fenêtre qui attend que l'on clique sur les boutons

***********************************************

2ième partie

On représente 2 balles en mouvement, une bleue et une rouge ; un bouton stop permet de figer le mouvement, on garde en mémoire le mouvement des balles pour les relancer dans l'état.

 

***********************************************

'''
Created on 23 août 2016

@author: vfsilesieux
'''
from random import randint

x,y=150,10
dx,dy=10,10
flag=0
speedx,speedy=10,10


def anime():
    b1.move()
    b2.move()
    fenetre.after(50,anime)#on boucle ainsi sur l'animation
def start():
    b1.start()
    b2.start()
    anime()
def stop():
    b1.stop()
    b2.stop()
from tkinter import *
fenetre = Tk()
fenetre.geometry("350x300")
can = Canvas(fenetre,bg="dark grey",height=250, width=250)
can.pack(side=LEFT,padx=5,pady=5)

boutonGO = Button(fenetre, text="GO", width =3,command=start)
boutonGO.pack(side=BOTTOM)
boutonSTOP = Button(fenetre, text="STOP", width =3,command=stop)
boutonSTOP.pack(side=BOTTOM)

class Balles(object):#on crée la classe Balles avec des propriétés et des méthodes
    def __init__(self, rayon, couleur,x,y,dx,dy):
        self.rayon=rayon
        self.couleur=couleur
        self.x=x
        self.dx=dx
        self.y=y
        self.dy=dy
        self.oval=can.create_oval(self.x,self.y,self.x+10,self.y+10,width=2,fill=self.couleur)
   
    def start(self):
        global flag
        flag=1
        self.dx,self.dy=speedx,speedy
        
    def stop(self):
        global speedx,speedy
        speedx,speedy=self.dx,self.dy
        global flag
        flag=0
        
    def move(self):
        
        if flag==0:     
            self.dx,self.dy=0,0
        if self.x>240:
            self.dx=-self.dx
        if self.x<10:
            self.dx=-self.dx
        if self.y<10:
            self.dy=-self.dy
        if self.y>240:
            self.dy=-self.dy
        self.x,self.y=self.x+self.dx,self.y+self.dy
        can.coords(self.oval,self.x,self.y,self.x+10,self.y+10)

#on crée deux instances de Balles

b1=Balles(2,"blue",10,20,5,5)
b2=Balles(2,"red",40,10,5,5)


fenetre.mainloop()

***********************************************

3ième partie : 20 balles en mouvement aléatoire avec un bouton d'arrêt et de reprise du mouvement

***********************************************
'''
Created on 23 août 2016
  
@author: vfsilesieux
'''
balles=[]#on crée une liste vide qui contiendra toutes les balles
from random import randint
  
x,y=150,10
dx,dy=10,10
flag=0

  
def anime():
    for i in range(0,len(balles)):#on anime toutes les balles de la liste balles
        balles[i].move()
    fenetre.after(50,anime)#on boucle l'animation sur elle-même
def start():
    global flag
    flag=1
    for i in range(0,len(balles)):
        balles[i].start()
    anime()
def stop():
    global flag
    flag=0
    for i in range(0,len(balles)):
        balles[i].stop()
        
from tkinter import *
fenetre = Tk()
fenetre.geometry("350x300")
can = Canvas(fenetre,bg="dark grey",height=250, width=250)
can.pack(side=LEFT,padx=5,pady=5)
  
boutonGO = Button(fenetre, text="GO", width =3,command=start)
boutonGO.pack(side=BOTTOM)
boutonSTOP = Button(fenetre, text="STOP", width =3,command=stop)
boutonSTOP.pack(side=BOTTOM)
  
class Balles(object):
    def __init__(self, rayon, couleur,x,y,dx,dy,oldspeedx,oldspeedy):
        self.rayon=rayon
        self.couleur=couleur
        self.x=x
        self.dx=dx
        self.y=y
        self.dy=dy
        self.oldspeedx=oldspeedx
        self.oldspeedy=oldspeedy
        self.oval=can.create_oval(self.x,self.y,self.x+10,self.y+10,width=2,fill=self.couleur)
     
    def start(self):
        self.dx,self.dy=self.oldspeedx,self.oldspeedy
                 
    def stop(self):
        self.oldspeedx,self.oldspeedy=self.dx,self.dy
        self.dx,self.dy=0,0
          
    def move(self):           
        if self.x>240:
            self.dx=-self.dx
        if self.x<10:
            self.dx=-self.dx
        if self.y<10:
            self.dy=-self.dy
        if self.y>240:
            self.dy=-self.dy
        self.x,self.y=self.x+self.dx,self.y+self.dy
        can.coords(self.oval,self.x,self.y,self.x+10,self.y+10)
  
for i in range(10):#on crée 10 balles bleues avec des vitesses aléatoires et en des positions aléatoires
    balles.append(Balles(2,"blue",randint(10,240),randint(10,240),0,0,randint(-2,2),randint(-2,2)))
   
for j in range(10):#on crée 10 balles rouges avec des vitesses aléatoires et en des positions aléatoires
    balles.append(Balles(2,"red",randint(10,240),randint(10,240),0,0,randint(-2,2),randint(-2,2)))
   
print (len(balles))
fenetre.mainloop()

***********************************************

4ième partie : 20 balles en mouvement aléatoire qui rebondissent l'une contre l'autre avec un bouton d'arrêt et de reprise du mouvement

'''
Created on 30 août 2016

@author: vfsilesieux
'''

balles=[]
from random import randint
from math import sqrt
   
x,y=150,10
dx,dy=10,10
flag=0
 
   
def anime():
    for i in range(0,len(balles)):
        balles[i].bounce()
        balles[i].move()  
    fenetre.after(50,anime)
def start():
    global flag
    flag=1
    for i in range(0,len(balles)):
        balles[i].start()
    anime()
def stop():
    global flag
    flag=0
    for i in range(0,len(balles)):
        balles[i].stop()
         
from tkinter import *
fenetre = Tk()
fenetre.geometry('350x300')
can = Canvas(fenetre,bg='dark grey',height=250, width=250)
can.pack(side=LEFT,padx=5,pady=5)
   
boutonGO = Button(fenetre, text='GO', width =3,command=start)
boutonGO.pack(side=BOTTOM)
boutonSTOP = Button(fenetre, text='STOP', width =3,command=stop)
boutonSTOP.pack(side=BOTTOM)
   
class Balles(object):
    def __init__(self, rayon, couleur,x,y,dx,dy,oldspeedx,oldspeedy,i,nextx,nexty):
        self.rayon=rayon
        self.couleur=couleur
        self.x=x
        self.dx=dx
        self.y=y
        self.dy=dy
        self.oldspeedx=oldspeedx
        self.oldspeedy=oldspeedy
        self.i=i
        self.nextx=nextx
        self.nexty=nexty
        
        self.oval=can.create_oval(self.x,self.y,self.x+10,self.y+10,width=2,fill=self.couleur)
      
    def start(self):
        self.dx,self.dy=self.oldspeedx,self.oldspeedy
                  
    def stop(self):
        self.oldspeedx,self.oldspeedy=self.dx,self.dy
        self.dx,self.dy=0,0
           
    def move(self):           
        if self.x>240:
            self.dx=-self.dx
        if self.x<10:
            self.dx=-self.dx
        if self.y<10:
            self.dy=-self.dy
        if self.y>240:
            self.dy=-self.dy
        self.x,self.y=self.x+self.dx,self.y+self.dy
        can.coords(self.oval,self.x,self.y,self.x+10,self.y+10)
    
    def bounce(self):#la méthode qui observe les collisions
#on regarde la position ultérieure de la balle pour prévoir la collision
        self.nextx=self.x+self.dx
        self.nexty=self.y+self.dy
        for k in range(0,len(balles)):
            if not k == self.i:
                distance=sqrt((self.nextx-balles[k].nextx)**2+(self.nexty-balles[k].nexty)**2)
                
                if distance<6:
                   
                    
                    memdx,memdy=self.dx,self.dy#on garde en mémoire le déplacement de la balle
#on échange les vitesses horizontales et verticales des deux balles
                    self.dx=sqrt(balles[k].dx**2+balles[k].dy**2)*(self.nextx-balles[k].nextx)/float(distance)
                    self.dy=sqrt(balles[k].dx**2+balles[k].dy**2)*(self.nexty-balles[k].nexty)/float(distance)
                    balles[k].dx=sqrt(memdx**2+memdy**2)*(balles[k].nextx-self.nextx)/float(distance)
                    balles[k].dy=sqrt(memdx**2+memdy**2)*(balles[k].nexty-self.nexty)/float(distance)
# on repositionne les balles à partir du milieu     
                    milieux=(self.nextx+balles[k].nextx)/2
                    milieuy=(self.nexty+balles[k].nexty)/2
                    memx,memy=self.nextx,self.nexty
                    self.x=milieux+3*(memx-balles[k].nextx)/float(distance)
                    self.y=milieuy+3*(memy-balles[k].nexty)/float(distance)
                    balles[k].x=milieux+3*(balles[k].nextx-memx)/float(distance)
                    balles[k].y=milieuy+3*(balles[k].nexty-memy)/float(distance)
                    
for i in range(0,10):
    balles.append(Balles(2,"blue",randint(10,240),randint(10,240),0,0,randint(-5,5),randint(-2,2),i,0,0))
    
for j in range(10,20):
    balles.append(Balles(2,"red",randint(10,240),randint(10,240),0,0,randint(-5,5),randint(-2,2),j,0,0))
    
print (len(balles))
fenetre.mainloop()

***********************************************

5ième partie : Création et gestion au clavier d'une boule verte

 

***********************************************

6ième partie : Vers le jeu, mais il reste du travail malgré des améliorations du code.

 

***********************************************

7ième partie : Il reste un problème à résoudre car lorsqu'on rejoue une partie les balles vont de plus en plus vite...