IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tkinter Python Discussion :

Balle qui rebondit [Python 3.X]


Sujet :

Tkinter Python

  1. #1
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut Balle qui rebondit
    Bonjour

    Nous sommes dans un canevas tkinter : c'est l'histoire d'une balle, qui part vers la droite, et quand elle atteint le bord du canevas elle repart vers la gauche, quand elle atteint le bord elle repart vers la droite, etc.....
    Je suis coincée là-dessus depuis hier après midi. Je ne comprends pas pourquoi mon code ne fonctionne pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    from tkinter import *
     
     
     
    def balle(i) :
        global x,y,n
        x[n] = x[n] + i
        can.coords(rond,x[n],y[n],x[n]+20,y[n]+20)
     
     
    def bouge() :
        n=1
        if x[n] > x[n-1] and x[n] <= 380:
            balle(10)
            if x[n] == 380 :
                balle(-10)
        if x[n] < x[n-1] and x[n] >= 0 :
            balle(-10)
            if x[n] == 0 :
                balle(10)
     
            balle(x[n])
     
    n = 1
    x = [180,190]
    y = [190,190]
     
    fen = Tk()
    fen.title('Balle qui rebondit')
     
    can = Canvas(fen,bg='pale goldenrod',width=400,height=400)
    can.pack()
     
    rond = can.create_oval(x[n],y[n],x[n]+20,y[n]+20,outline='firebrick1',fill='firebrick1')
     
    Button(fen,text='Bouge !',bg='pale goldenrod',fg='firebrick1',command=bouge).pack(side=BOTTOM)
     
    fen.mainloop()
    Malheureusement, là elle va bien vers la droite...mais c'est tout, je n'arrive pas à la faire revenir. J'ai tout essayé. Enfin non pas tout puisque ça ne marche pas, donc j'ai tout essayé sauf la bonne solution

    Est-ce que vous pourriez me mettre sur la voie S.V.P. ?

    Merci

  2. #2
    Membre émérite

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Points : 2 328
    Points
    2 328
    Par défaut
    Regarde les conditions de ta fonction bouge :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def bouge() :
    .....
        if x[n] > x[n-1] and x[n] <= 380:
            ....
        if x[n] < x[n-1] and x[n] >= 0 :
            .....
    Au départ tu bouge vers la droite. Donc x[n] > x[n-1] est toujours vérifié. Lorsque tu atteint le mur, x[n] vaut surement 381, mais x[n-1] vaut 380. Donc tu ne vérifies aucune des 2 conditions

  3. #3
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Au début j'avais mis while, justement pour cadrer mon X[n], mais ça ne fonctionne pas non plus, encore moins bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def bouge() :
        n=1
        while 0 <= x[n] <=380  : 
            if x[n] > x[n-1] :
                balle(10)
                if x[n] == 380 :
                    balle(-10)
            if x[n] < x[n-1]  :
                balle(-10)
                if x[n] == 0 :
                    balle(10)
     
            balle(x[n])
    Du moins je suis sur la bonne voie non ?
    Parce que je commence à douter là en fait

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 781
    Points
    36 781
    Par défaut
    Salut,

    Quand vous avez ce genre de soucis, l'instruction "print" permet de vous afficher l'état de vos variables et de vous posez des questions lorsque leurs valeurs ne sont pas celles attendues.
    Ajoutez un print (x[n], x[n-1]) juste après l'entrée dans la fonction "bouge"...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    190 et 180. C'est ce que je croyais que c'était

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def bouge() :
        n=1
        while 0 <= x[n] <=380  : 
            if x[n] > x[n-1] :
                balle(10)
                if x[n] == 380 :
                    balle(-10)
            if x[n] < x[n-1]  :
                balle(-10)
                if x[n] == 0 :
                    balle(10)
    Là, moi j'ai l'impression de lui dire :
    Tant que x (190 pour l'instant) est compris entre 0 et 380,
    si x est > au précédent x de la liste alors on continue, on fait +10, jusqu'à 380 maxi
    si x égal à 380, alors on recule, on fait -10
    si x est < au précédent x de la liste, alors on fait -10 jusque 0 maxi
    et si x égal 0, alors on repart dans l'autre sens, on fait +10

    Mais ce n'est pas ce que Python comprend

    Edit : Ah oui, j'ai cliqué plusieurs fois sur mon bouton, j'ai vu l'évolution de mes x, en effet je vois le problème. Enfin je ai pas encore identifié la cause mais j'avance

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 037
    Points
    31 037
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par RowanMayfair Voir le message
    si x est > au précédent x de la liste alors on continue, on fait +10, jusqu'à 380 maxi
    si x égal à 380, alors on recule, on fait -10
    Plutôt que d'avancer et de reculer ensuite si tu dépasses, peut-être tu pourrais regarder si tu peux avancer avant d'avancer...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    mais c'est le but justement de reculer.
    La "balle" est censée avancer jusqu'au bord du canevas, puis reculer jusqu'à l'autre bord du canevas.

    Ceci dit, j'ai toujours pas la solution. Pas trop le temps non plus, de temps en temps j'y jette un oeil et essaie des trucs mais.....il fait toujours pas ce que je veux

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 781
    Points
    36 781
    Par défaut
    Citation Envoyé par RowanMayfair Voir le message
    La "balle" est censée avancer jusqu'au bord du canevas, puis reculer jusqu'à l'autre bord du canevas.
    Pour reculer, il faudrait que la condition x[n] < x[n-1] puisse être vraie... ce qui suppose que x[n-1] soit mis à jour alors qu'il a tout le temps la même valeur.
    N'oublier pas que Python ne se permettra jamais d'exécuter des instructions que vous n'avez pas écrites.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 037
    Points
    31 037
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par RowanMayfair Voir le message
    mais c'est le but justement de reculer.
    La "balle" est censée avancer jusqu'au bord du canevas, puis reculer jusqu'à l'autre bord du canevas.
    Oui je comprends bien que pour la faire "rebondir" il faut la faire aller dans un sens puis dans l'autre.

    Ce que je trouve "bancal", c'est que dans un cycle de mouvement (le while), dans certains cas la balle fasse un mouvement et dans d'autres cas elle en fera deux. Je pense que visuellement ça produira un effet saccadé.
    J'aurais plutôt mieux vu "un tour => un changement de position => un affichage"...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 781
    Points
    36 781
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    dans certains cas la balle fasse un mouvement et dans d'autres cas elle en fera deux. Je pense que visuellement ça produira un effet saccadé.
    Même pas: c'est dans le même callback, donc les mouvements attendent dans la boucle d'évènement attendant le "return"... qui permettra à tk de la vider et d'optimiser: il va calculer la position finale avant de mettre à jour l'affichage.
    Note: en fait, c'est pas tk qui fait çà mais le serveur X11(*) / display manager de l'environnement.
    (*) une techno. qui date des années 80s.
    I've been there and got a sweet çà s'appelait le project Athena.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Pour reculer, il faudrait que la condition x[n] < x[n-1] puisse être vraie... ce qui suppose que x[n-1] soit mis à jour alors qu'il a tout le temps la même valeur.
    N'oublier pas que Python ne se permettra jamais d'exécuter des instructions que vous n'avez pas écrites.

    - W
    Mais OUIIIIIIIIIIIII

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    from tkinter import *
     
     
    def balle(i) :
        "fonction qui dessine la balle"
        global x,y,n
        x[n-1] +=  i
        x[n] +=  i
        can.coords(rond,x[n],y[n],x[n]+20,y[n]+20)
     
     
    def bouge() :
        "fonction qui créé le mouvement de la balle, et mime son rebond contre le bord du canevas"
        n = 1
        if x[n] > x[n-1]:
            balle(10)
     
        if x[n] == 390 :
            x[n] -= 20
     
        if x[n] < x[n-1] :
            balle(-10)
     
        if x[n-1] == 10 :
            x[n] += 20
     
            balle(x[n])
     
     
     
     
    x = [180,190]
    y = [190,190]
    n = 1



    Merci merci MERCI wiztricks

    Je ne sais pas si mon code est très "beau", il révèle probablement mes toutes petites connaissances, mais ça MARCHE !

    Depuis le temps qu'elle se tapait la tête contre cette pauvre balle, il était temps, je désespérait là


    Edit : avec while.....j'avais une boucle qui rebondissait entre 0 et 380 à l'infini mais la balle bougeait pas, elle

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 037
    Points
    31 037
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par RowanMayfair Voir le message
    Je ne sais pas si mon code est très "beau",
    Non pas très.

    En dehors de l'effet "saccadé" dont j'avais parlé et qui est bel et bien présent (quand la balle arrive au mur de droite, au mouvement suivant elle est "trop" à gauche de ce qu'on s'attend à voir... et arrivé au mur de gauche elle rebondit bien avant de taper le mur), le principal défaut c'est que ta fonction "balle" (qui est destinée à priori à afficher la balle) modifie aussi sa position. Et ça ce n'est pas cohérent (normalement cela devrait être dévolu à la fonction "bouge"). Bref dans la prog "atomique" on essaye de privilégier "une action=une fonction".
    D'autant plus que ça aide pas à comprendre ces deux lignes
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    x[n] += 20
    balle(x[n])
    car la première ligne indique une modification de x[n] (ok) mais comme la fonction "balle" modifie aussi x[n] en lui rajoutant la valeur reçue (x[n] sera alors doublé ?), on perd rapidement le fil pour essayer de suivre dans ton algo le cheminement de la balle.

    Et puis ces x[n] et x[n-1] n'aident pas non plus. Généralement on utilise cette notation quand "n" varie. Mais là, il ne varie pas. Tu peux pas écrire directement x[1] et x[0] ? Moins il y aura de variables inutiles, plus ton code sera facile à suivre. Surtout qu'il y a d'autres façons de gérer un sens de déplacement que de comparer les grandeurs respectives des deux dernières positions.

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    def balle(rond, x, y, diametre) :
    	"fonction qui dessine la balle à une position"
    	can.coords(rond, x, y, x+diametre, y+diametre)
     
    def bouge() :
    	"fonction qui créé le mouvement de la balle, et mime son rebond contre le bord du canevas"
    	global x, y, poussee
     
    	x=x + poussee
     
    	if x+diametre >= width:
    		poussee=-poussee
    		x=width-diametre
    	if x-diametre <= -diametre:
    		poussee=-poussee
    		x=0
     
    	balle(rond, x, y, diametre)
     
    poussee=10
    x=180
    y=190
    width=400
    height=400
    diametre=20
     
    fen = Tk()
    fen.title('Balle qui rebondit')
     
    can = Canvas(fen,bg='pale goldenrod',width=width,height=width)
    can.pack()
     
    rond=can.create_oval(x, y, x, y, outline='firebrick1', fill='firebrick1')
    balle(rond, x, y, diametre)
     
    Button(fen,text='Bouge !',bg='pale goldenrod',fg='firebrick1',command=bouge).pack(side=BOTTOM)
     
    fen.mainloop()

    Il y a un petit déséquilibre dans la gestion du bord gauche et du bord droit (et j'en ai chié pour le régler). C'est parce que le (0, 0) de la balle n'est pas au centre de la balle mais sur l'un de ses "coins".

    Si on réécrit l'affichage de la balle ainsi...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def balle(rond, x, y, diametre) :
    	"fonction qui dessine la balle à une position"
    	can.coords(rond, x-diametre/2, y-diametre/2, x+diametre/2, y+diametre/2)

    ...alors la gestion des bords devient plus symétrique
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if x >= width:
    	poussee=-poussee
    	x=width-diametre
    if x <= 0:
    	poussee=-poussee
    	x=diametre

    Ce qui permet ensuite de monter facilement à un rebond en X et en Y
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    def balle(rond, x, y, diametre) :
    	"fonction qui dessine la balle à une position"
    	can.coords(rond, x-diametre/2, y-diametre/2, x+diametre/2, y+diametre/2)
     
    def bouge() :
    	"fonction qui créé le mouvement de la balle, et mime son rebond contre le bord du canevas"
    	global x, y, poussee
     
    	x=x + poussee["x"]
    	y=y + poussee["y"]
     
    	if x >= width:
    		poussee["x"]=-poussee["x"]
    		x=width-diametre
    	if x <= 0:
    		poussee["x"]=-poussee["x"]
    		x=diametre
    	if y >= height:
    		poussee["y"]=-poussee["y"]
    		y=height-diametre
    	if y <= 0:
    		poussee["y"]=-poussee["y"]
    		y=diametre
     
    	balle(rond, x, y, diametre)
     
    poussee={"x" : 10, "y" : 10}
    x=180
    y=190
    width=400
    height=400
    diametre=20
     
    fen = Tk()
    fen.title('Balle qui rebondit')
     
    can = Canvas(fen,bg='pale goldenrod',width=width,height=width)
    can.pack()
     
    rond=can.create_oval(x, y, x, y, outline='firebrick1', fill='firebrick1')
    balle(rond, x, y, diametre)
     
    Button(fen,text='Bouge !',bg='pale goldenrod',fg='firebrick1',command=bouge).pack(side=BOTTOM)
     
    fen.mainloop()

    Citation Envoyé par RowanMayfair Voir le message
    Je ne sais pas si mon code est très "beau",
    Ce n'est pas qu'une question de "beauté" mais surtout d'évolutivité. Plus tes fonctions seront simples dans leurs opérations, plus tu pourras les agglomérer facilement dans un sens ou dans l'autre pour faire évoluer ton code dans un sens ou dans l'autre.

    Si par exemple je veux pas m'embêter à rappuyer à chaque fois sur le bouton...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    "fonction qui dessine la balle à une position"
    balle=lambda rond, x, y: can.coords(rond, x-diametre/2, y-diametre/2, x+diametre/2, y+diametre/2)
     
    def bouge() :
    	"fonction qui créé le mouvement de la balle, et mime son rebond contre le bord du canevas"
    	global x, y, poussee
     
    	while True:
    		x=x + poussee["x"]
    		y=y + poussee["y"]
     
    		if x >= width:
    			poussee["x"]=-poussee["x"]
    			x=width-diametre
    		if x <= 0:
    			poussee["x"]=-poussee["x"]
    			x=diametre
    		if y >= height:
    			poussee["y"]=-poussee["y"]
    			y=height-diametre
    		if y <= 0:
    			poussee["y"]=-poussee["y"]
    			y=diametre
     
    		fen.after(int(refresh * 100), balle(rond, x, y))
    		Tk.update(fen)
    	# while
    # bouge()
     
    poussee={"x" : 10, "y" : 20}
    x=180
    y=190
    width=400
    height=400
    diametre=20
    refresh=0.1
     
    fen = Tk()
    fen.title('Balle qui rebondit')
     
    can = Canvas(fen,bg='pale goldenrod',width=width,height=width)
    can.pack()
     
    rond=can.create_oval(x, y, x, y, outline='firebrick1', fill='firebrick1')
    balle(rond, x, y)
     
    Button(fen,text='Bouge !',bg='pale goldenrod',fg='firebrick1',command=bouge).pack(side=BOTTOM)
     
    fen.mainloop()

    Toutefois, la simplicité est souvent naturellement associée à une certaine "beauté"...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 781
    Points
    36 781
    Par défaut
    Salut,

    Citation Envoyé par RowanMayfair Voir le message
    Je ne sais pas si mon code est très "beau", il révèle probablement mes toutes petites connaissances, mais ça MARCHE !
    Vous débutez, çà ne peut pas être beau... et si vous avez la patience de revoir ce bout de code dans quelques semaines, vous le trouverez certainement très moche.
    Mais, l'important est tout ce que vous avez appris en essayant de le faire fonctionner: la qualité du code est (pour l'instant) sans importance.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  14. #14
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Non pas très.

    En dehors de l'effet "saccadé" dont j'avais parlé et qui est bel et bien présent (quand la balle arrive au mur de droite, au mouvement suivant elle est "trop" à gauche de ce qu'on s'attend à voir... et arrivé au mur de gauche elle rebondit bien avant de taper le mur), le principal défaut c'est que ta fonction "balle" (qui est destinée à priori à afficher la balle) modifie aussi sa position. Et ça ce n'est pas cohérent (normalement cela devrait être dévolu à la fonction "bouge"). Bref dans la prog "atomique" on essaye de privilégier "une action=une fonction".
    D'autant plus que ça aide pas à comprendre ces deux lignes
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    x[n] += 20
    balle(x[n])
    car la première ligne indique une modification de x[n] (ok) mais comme la fonction "balle" modifie aussi x[n] en lui rajoutant la valeur reçue (x[n] sera alors doublé ?), on perd rapidement le fil pour essayer de suivre dans ton algo le cheminement de la balle.

    Et puis ces x[n] et x[n-1] n'aident pas non plus. Généralement on utilise cette notation quand "n" varie. Mais là, il ne varie pas. Tu peux pas écrire directement x[1] et x[0] ? Moins il y aura de variables inutiles, plus ton code sera facile à suivre. Surtout qu'il y a d'autres façons de gérer un sens de déplacement que de comparer les grandeurs respectives des deux dernières positions.
    Ah...mes x[n] et x[n-1], là je suis parfaitement d'accord.
    C'est parce qu'au moment de commencer, j'étais partie sur une autre idée pour obtenir mon résultat : je pensais simplement qu'à chaque déplacement de la balle, les coordonnées allaient s'incrémenter dans ma liste. Toutes seules, comme par magie .
    Peut-être pas.
    Bref, dans mon code d'origine, il y avait pleins de dans ma fonction "bouge". Et j'avais Tel que je le voyais, les coordonnées successives s'ajoutaient donc à ma liste, x[n] était donc toujours la dernière de ces coordonnées. Pour ça que je ne touchait pas à mon x[n-1] dans ma fonction, puisque pour moi c'était l'avant dernière coordonnée de la liste. Et c'est tout.
    Et ça fonctionnait...pas comme je voulais.
    Pour une mystérieuse raison, en effet les nouvelles coordonnées s'ajoutaient à ma liste, mais le X[n] restait fixe lui. Du coup son prédécesseur aussi.
    Donc y a un truc que j'ai pas compris/ou que je ne sais pas au sujet des listes.


    (...)

    l y a un petit déséquilibre dans la gestion du bord gauche et du bord droit (et j'en ai chié pour le régler). C'est parce que le (0, 0) de la balle n'est pas au centre de la balle mais sur l'un de ses "coins".
    m'en parle pas. J'ai essayé 5 minutes en vrai, j'avoue ne pas avoir passé de temps là-dessus. J'étais tellement contente de voir ma balle revenir que la qualité de son demi-tour....je me suis dit que ce serait pour la prochaine fois

    (...)


    Ce n'est pas qu'une question de "beauté" mais surtout d'évolutivité. Plus tes fonctions seront simples dans leurs opérations, plus tu pourras les agglomérer facilement dans un sens ou dans l'autre pour faire évoluer ton code dans un sens ou dans l'autre.

    Si par exemple je veux pas m'embêter à rappuyer à chaque fois sur le bouton...
    Ah mais si, on s'embête à appuyer sur le bouton
    L'énoncé de l'exercice : "Chaque fois que l'on clique sur le bouton, la balle doit avancer d'une petite distance vers la droite, jusqu'à ce qu'elle atteigne l'extrémité du canevas. Si l'on continue à cliquer, la balle doit alors revenir en arrière jusqu'à l'autre extrémité, et ainsi de suite."
    C'est le 8.17 du bouquin de Swinnen https://python.developpez.com/cours/...=page_10#L10-G
    Ah ben non c'est pas le 8.17 sur le bouquin à l'écran je l'ai acheté, je croyais que c'était les mêmes(le livre à l'écran et celui papier), mais il y a des différences il semble.

  15. #15
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 037
    Points
    31 037
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par RowanMayfair Voir le message
    Pour une mystérieuse raison, en effet les nouvelles coordonnées s'ajoutaient à ma liste, mais le X[n] restait fixe lui. Du coup son prédécesseur aussi.
    Donc y a un truc que j'ai pas compris/ou que je ne sais pas au sujet des listes.
    Sans voir le code, difficile de donner un avis.
    Une hypothèse cependant: peut-être que tu modifiais la liste tout en itérant dessus. C'est une erreur assez fréquente quand on débute => ex
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    tab=[0,]
    for x in tab:
        print(x)
        tab.append(x+1)
    => boucle infinie. On ne modifie jamais un tableau sur lequel on itère. Si on doit en arriver là, alors on itère sur une copie du tableau
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    tab=[0,]
    for x in tuple(tab):
        print(x)
        tab.append(x+1)
    La fonction tuple() appliquée à un tableau crée un tuple copie du tableau (on peut aussi utiliser la fonction list() mais pourquoi créer une liste quand un tuple suffit ?)

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    tab=[0,]
    for x in tab[:]:
        print(x)
        tab.append(x+1)
    Le slice [:] appliqué à un tableau crée aussi une copie du tableau

    Citation Envoyé par RowanMayfair Voir le message
    Ah mais si, on s'embête à appuyer sur le bouton
    C'était juste pour illustrer un exemple de modification possible. Enfin essaye quand-même mon code, tu verras c'est pas mal. Et en jouant sur les paramètres ça varie les effets...
    Ne reste qu'à rajouter la fonction sinusoïdale d'amorti et le truc sera parfait


    Citation Envoyé par RowanMayfair Voir le message
    Ah ben non c'est pas le 8.17 sur le bouquin à l'écran je l'ai acheté,
    Ah c'est toi ! Oui, en effet sur les forums on raconte qu'il y a quelqu'un qui a acheté le bouquin gratuit de Swinnen et on cherchait à savoir de qui il s'agissait
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  16. #16
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    ah ah oui c'est moi qui achète les trucs gratuits

  17. #17
    Futur Membre du Club
    Homme Profil pro
    Débutant
    Inscrit en
    Novembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Novembre 2019
    Messages : 4
    Points : 6
    Points
    6
    Par défaut
    Bonjour à tous,
    je viens de m'inscrire sur ce forum en cherchant la solution à ce problème.

    vous m'avez bien aidé en m'orientant sur du IF à la place du while et je ne résiste pas à l'envie de vous poster la solution que j'ai trouvé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    from tkinter import *
     
    def deplacement(xp,yp):
        global x,y
        x,y=xp,yp
        cadre.coords(balle,xp-10,yp-10,xp+10,yp+10)
     
    def droite():
        deplacement(x + 10, y)
     
    def gauche():
        deplacement(x - 10, y)
     
    def alterner ():
        global x,y,lar
        if x<lar:
            droite()
        elif x>=lar:
            gauche()
            lar=lar-20
            if x==0:
                lar=200
     
    x,y=20,20
    lar = 200
     
     
    fen = Tk()
    cadre = Canvas(fen, width =200, height =150, bg="light yellow")
    cadre.pack()
    balle = cadre.create_oval(x-10, y-10, x+10, y+10,fill ="red", width =1)
    bou1=Button(fen,text="QUITTER",command=fen.quit)
    bou1.pack(side=BOTTOM)
    bou2=Button(fen,text= "déplacement",command=alterner)
    bou2.pack(side=TOP)
    fen.mainloop()
    voilà, merci et bonne journée à tous.

  18. #18
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 037
    Points
    31 037
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par krwiss Voir le message
    vous m'avez bien aidé en m'orientant sur du IF à la place du while
    Moui... les deux instructions n'ayant pas du tout le même but, je ne comprends même pas comment tu peux ne serait-ce que songer à faire la confusion. Si tu veux boucler il te faut du "while" et si tu veux juste choisir entre 2 possibilités il te faut du "if". Et comme c'est toi qui sait ce que tu veux faire...

    Citation Envoyé par krwiss Voir le message
    et je ne résiste pas à l'envie de vous poster la solution que j'ai trouvé.
    Bel effort. Toutefois je ne comprends pas trop le rôle de la variable "lar". Accessoirement le "elif" est de trop (il est évident que si "x < lar" est faux, alors c'est que x obligatoirement >= lar et donc inutile même de le tester.
    De même les fonctions "droite" et "gauche" sont un peu trop semblables pour ne pas être regroupées.
    Et attention à ne pas user inconsidérément de globales. Dans Python toutes les variables défines hors de toute fonction sont automatiquement connues de tout le source en lecture. Donc si une fonction n'a pas besoin de modifier une variable, pas besoin de la redéfinir en "globals".
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  19. #19
    Futur Membre du Club
    Homme Profil pro
    Débutant
    Inscrit en
    Novembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Novembre 2019
    Messages : 4
    Points : 6
    Points
    6
    Par défaut
    J ai hésité sur while car la repetition de boutons m avait dérouté vers une sorte de boucle. ( on appuie sur le bouton jusqu'à ce que...) et donc oui content d avoir lu vos posts pour ça. Après je débute clairement et mes solutions, je les trouve en tatonnant. En utlisant pas lar je n arrivais pas à faire revenir la balle jusqu'au debut du cadre. Avec lar, oui. Donc voilà. Pour le reste merci pour les conseils et remarques. j en prends bonne note. Bonne soirée et merci encore

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Python 3.X] Balle qui rebondit
    Par RowanMayfair dans le forum Général Python
    Réponses: 3
    Dernier message: 12/04/2019, 14h00
  2. Réponses: 0
    Dernier message: 21/05/2018, 17h13
  3. Balle qui ne bouge que si ej bouge la souris
    Par Thinking dans le forum SFML
    Réponses: 1
    Dernier message: 29/12/2014, 15h39
  4. [CS3] une balle qui rebondit de tout les cotés du document
    Par carasmel dans le forum ActionScript 1 & ActionScript 2
    Réponses: 2
    Dernier message: 08/07/2011, 13h00
  5. pygame ballon qui rebondit
    Par Invité dans le forum GUI
    Réponses: 2
    Dernier message: 23/01/2010, 02h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo