Forum Programmation.python Mon programme ne fonctionne pas comme je veux

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
1
9
avr.
2018

`Bonjour,

J'ai écrit un programme Python de déplacement de bille dans un cadre avec rebondissement sur les bords du cadre. Mon problème c'est quand je lance le programme avec le nombre de bille N>1, seule une seule bille bouge et les autres restent fixent. Quelqu'un peut m'aider?
Voici le programme :

    from tkinter import *
    from random import *

    class bille:
        def __init__(self):
            self.i=0
            self.x=0
            self.y=0
            self.dx=0
            self.dy=0
        def deplace(self,balle):
            canvas.move(balle[self.i],self.dx,self.dy)
            self.x=canvas.coords(balle[self.i])[2]
            self.y=canvas.coords(balle[self.i])[3]
            bille.mur(self)
            tk.after(20,bille.deplace,self,balle)

        def mur(self):
            if not(20 < self.y < 310):
                 self.dy=(-1)*self.dy
            if not(20 < self.x < 470):
                self.dx=(-1)*self.dx

    def demarrer():
        N=3
        cx,cy,tdx,tdy,balle=[1]*N,[1]*N,[1]*N,[1]*N,[1]*N
        for l in range(N):
            cx[l],cy[l]=randint(30,420),randint(30,250)
            tdx[l],tdy[l]=4,4
        for i in range(N):
            balle[l]=canvas.create_oval(cx[i],cy[i],cx[i]+15,cy[i]+15,fill='white',outline='black')
        for i in range(N):
            p=bille()
            p.i=i
            p.x=cx[i]
            p.y=cy[i]
            p.dx=tdx[i]
            p.dy=tdy[i]
            p.deplace(balle)

    #Programme Principal
    tk=Tk()
    canvas=Canvas(tk,width = 480, height = 320 , bd=0, bg="yellow")
    canvas.pack()
    #Creation d'un bouton "Démarrer"
    Boutton_Demarrer=Button(tk,text="Démarrer",command=demarrer)
    Boutton_Demarrer.pack(side=LEFT)
    #Creation d'un bouton "Detruire":
    Bouton_Detruire=Button(tk, text ='Quitter', command = tk.destroy)
    #Ajouter l'affichage du bouton dans la fenêtre tk:
    Bouton_Detruire.pack(side=RIGHT)
    #Boucle principale:
    tk.mainloop()
  • # Boucle infinie

    Posté par  (site web personnel) . Évalué à 3.

    J'ai du mal à croire que ton programme fonctionne même avec une seule bille. Pour cela il faudrait quand tu appuies sur ton bouton démarrer créer les billes, puis te débrouiller pour que dans sa boucle infinie TK appelle une autre fonction toutes les 15 ms par exemple (pour 60 images par seconde) qui elle déplace tes billes et demande un ré-affichage. Là ta fonction demarrer() est juste appelée une fois quand tu cliques sur le bouton…

    • [^] # Re: Boucle infinie

      Posté par  . Évalué à 3.

      Pourtant ça fonctionne avec une seule bille. Il y a l'instruction tk.after qui rappelle la fonction deplace toutes les 20ms.

      • [^] # Re: Boucle infinie

        Posté par  (site web personnel) . Évalué à 3.

        Ah oui en effet je ne l'avais pas vu ; mis à part que je trouve ça globalement moche que after() soit appelée N fois au lieu d'une seule, est-ce que ça ne serait pas là le problème (je précise que je ne connais pas spécialement Tk) ?

  • # Erreur d'indice ?

    Posté par  . Évalué à 5.

    for i in range(N):
                balle[l]=canvas.create_oval(cx[i],cy[i],cx[i]+15,cy[i]+15,fill='white',outline='black')

    peut-être ici, une boucle avec i et balle indexée avec l alors que la boucle l est terminée ?

  • # Encore un problème : Carbage collector me joue des tours

    Posté par  . Évalué à -1.

    En reprenant le programme ci-dessus, j’ai voulu placer le nombre de billes N en paramètre pouvant être modifié par l’utilisateur ( bouton Entry). Ca marche, sauf que lorsque l’utilisateur change la valeur de N, on obtient un message d’erreur :
    *Exception in Tkinter callback
    Traceback (most recent call last):
    File "/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/
    init.py", line 1699, in __call_
    return self.func(*args)
    File "/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/init.py", line 745, in callit
    func(*args)
    File "/Users/foccus/Desktop/Python/Code2/tes1.py", line 13, in deplace
    self.x=canvas.coords(balle[self.i])[2]
    IndexError: list index out of range_
    *

    Le programme :

    ``from tkinter import *
    from random import *

    class bille:
    def init(self):
    self.i=0
    self.x=0
    self.y=0
    self.dx=0
    self.dy=0
    def deplace(self,balle):
    canvas.move(balle[self.i],self.dx,self.dy)
    self.x=canvas.coords(balle[self.i])[2]
    self.y=canvas.coords(balle[self.i])[3]
    bille.mur(self)
    tk.after(20,bille.deplace,self,balle)

    def mur(self):
    if not(20 < self.y < 310):
    self.dy=(-1)*self.dy
    if not(20 < self.x < 470):
    self.dx=(-1)*self.dx
    def demarrer():

    canvas.delete(ALL)
    EN=entree_N.get()
    N=int(EN)
    cx,cy,tdx,tdy,balle=[1]*N,[1]*N,[1]*N,[1]*N,[1]*N
    for l in range(N):
        cx[l],cy[l]=randint(30,420),randint(30,250)
        tdx[l],tdy[l]=4,4
    for i in range(N):
        balle[i]=canvas.create_oval(cx[i],cy[i],cx[i]+15,cy[i]+15,fill='white',outline='black')
    for i in range(N):
        p=bille()
        p.i=i
        p.x=cx[i]
        p.y=cy[i]
        p.dx=tdx[i]
        p.dy=tdy[i]
        p.deplace(balle)
    

    Programme Principal

    tk=Tk()
    canvas=Canvas(tk,width = 480, height = 320 , bd=0, bg="yellow")
    canvas.pack()

    Creation d'un bouton "Démarrer"

    Boutton_Demarrer=Button(tk,text="Démarrer",command=demarrer)
    Boutton_Demarrer.pack(side=LEFT)

    Creation d'un bouton "Detruire":

    Bouton_Detruire=Button(tk, text ='Quitter', command = tk.destroy)

    Ajouter l'affichage du bouton dans la fenêtre tk:

    Bouton_Detruire.pack(side=RIGHT)

    Nombre de balles N

    entree_N=Entry(tk,width=3)
    entree_N.pack()

    Boucle principale:

    tk.mainloop()`

    `

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.