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 :

Faire rebondir une balle [Python 3.X]


Sujet :

Tkinter Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2018
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2018
    Messages : 3
    Par défaut Faire rebondir une balle
    Bonjour à tous,

    même si je lis pas mal de sujet sur ce forum, je n'arrive pas à résoudre mon problème. Je débute en Python et mon script est sans doute mal écrit.

    Objectif : Faire rebondir une balle d'une hauteur de 200 px, px par px, avec un affichage toutes les 0,5 secondes (ce qui doit prendre 20 s)
    Remarque : J'ai ajouté une balle jaune pour visualiser la position initiale de la balle rouge et pour le moment la balle rouge se contente de monter pour que je puisse constater que ma fonction fonctionne.

    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
    "Importation des bibliothèques"
    from tkinter import *
     
    "Définition des fonctions"
    def deplacement(dy , nb): # Déplace balle1 "nb" fois de "dy" selon y
        global nb_aff
        while (nb_aff <= nb):
            nb_aff += 1
            Can.move(balle1,0,dy)
            Fen.after(500,deplacement(dy,nb))
     
    def rebond():
        nb_aff = 0
        deplacement(-1,200) # Déplace la balle1 de 200 px vers le haut de 1 px en 1 px
        #deplacement(1,200) # Déplace la balle1 de 200 px vers le bas de 1 px en 1 px
     
    Fen = Tk()
    Fen.title('Faire rebondir une balle')
     
    Can = Canvas(Fen , width = 400 , height = 300 , background = 'white')
    Can.pack()
    balle2 = Can.create_oval(40 , 280 , 60 , 300 , fill='yellow') # Balle fixe jaune
    balle1 = Can.create_oval(40 , 280 , 60 , 300 , fill='red') # Balle qui doit rebondir
    nb_aff = 0
    rebond()
     
    Fen.mainloop()
    Problème : La fenêtre nommée Fen ne s'affiche que lorsque la balle rouge a effectué son saut, enfin, que la première partie, c'est à dire après 10 s, or j'aimerais visualiser le déplacement de la bille rouge ...

    Je suis preneur de toute proposition même si le code est totalement revu.

    Par avance, merci.

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 752
    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 752
    Par défaut
    Salut,

    Citation Envoyé par _mathsrimb_ Voir le message
    Je suis preneur de toute proposition même si le code est totalement revu.
    Mettez en commentaire la ligne 10 (Fen.after(500...)))et regardez ce qu'il se passe.

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

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2018
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2018
    Messages : 3
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,



    Mettez en commentaire la ligne 10 (Fen.after(500...)))et regardez ce qu'il se passe.

    - W
    Bonjour,
    j'y avais déjà pensé et c'est cette ligne qui génère l'affichage tardif de la fenêtre. D'un autre côté, sans une temporisation, la balle rouge monte si vite que ce n'est pas perceptible, or j'aimerais que ça le soit. J'ai fait des recherches sur cette instruction, mais je n'arrive pas à déceler le problème.
    A une (vieille) époque, une boucle For vide permettait de temporiser en comptant sur la lenteur des processeurs, plus maintenant.

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 752
    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 752
    Par défaut
    Citation Envoyé par _mathsrimb_ Voir le message
    j'y avais déjà pensé et c'est cette ligne qui génère l'affichage tardif de la fenêtre. D'un autre côté, sans une temporisation, la balle rouge monte si vite que ce n'est pas perceptible, or j'aimerais que ça le soit. J'ai fait des recherches sur cette instruction, mais je n'arrive pas à déceler le problème.
    Il n'y a pas de problème côté code, juste que vous ne comprenez pas trop ce qu'il se passe (et pourquoi il n'est pas possible de faire cela ainsi).
    Si vous écrivez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def deplacement(dy , nb): # Déplace balle1 "nb" fois de "dy" selon y
        global nb_aff
        while (nb_aff <= nb):
            nb_aff += 1
            Can.move(balle1,0,dy)
            Fen.after(500,deplacement(dy,nb))
    vous appelez "nb" fois deplacement(dy,nb) immédiatement et non une seule fois dans 500 ms (à cause de l'indentation). Pour lui dire d'appeler la fonction (avec ces paramètres) "plus tard", il faut revoir la syntaxe ou utiliser des lambda... (mais comme nf_aff n'est pas remis à zéro, çà ne fera pas grand chose).

    De plus, appeler nb fois Can.move(balle1,0,dy) ou une seule fois Can.move(balle1,0, nb*dy) aura visuellement le même effet.

    Vous avez des exemples d'animations dans le Swinnen qui pourraient vous donner des idées ou vous inspirer de celui-ci
    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    import tkinter as tk
     
    DV = 5
    DELAY = 50
     
    motion_timer = None
    motion_key = None
    motion_deltas = {
        'Left': (-DV, 0),
        'Right': (DV, 0),
        'Up': (0, -DV),
        'Down': (0, DV),
        }
     
    def do_motion(canvas, dx, dy):
     
        def _doit():
            global motion_timer
     
            canvas.move('bille', dx, dy)
            motion_timer = canvas.after(DELAY, _doit)
     
        _doit()
     
    def on_key_press(canvas, keysym):
        global motion_timer, motion_key
     
        if motion_key != keysym:
            if motion_timer is not None:
                canvas.after_cancel(motion_timer)
                motion_timer = None
     
            motion_key = keysym
            do_motion(canvas, *motion_deltas[keysym])
     
    if __name__ == '__main__':
     
        root = tk.Tk()
        root.event_add('<<PressArrows>>',
                       '<KeyPress-Left>', '<KeyPress-Right>',
                       '<KeyPress-Up>', '<KeyPress-Down>')
        canvas = tk.Canvas(width=600, height=600, bg='white')
     
        canvas.bind('<<PressArrows>>', lambda e: on_key_press(e.widget, e.keysym))
     
        canvas.create_oval(100, 100, 115, 115, fill='red', tag='bille')
     
        canvas.pack()
        canvas.focus_set()
        on_key_press(canvas, 'Right')
        tk.mainloop()
    (récupéré dans un vieux post)



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

  5. #5
    Invité de passage
    Homme Profil pro
    Responsable d'explotation
    Inscrit en
    Février 2018
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Responsable d'explotation
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2018
    Messages : 1
    Par défaut
    Citation Envoyé par _mathsrimb_ Voir le message
    Bonjour à tous,

    même si je lis pas mal de sujet sur ce forum, je n'arrive pas à résoudre mon problème. Je débute en Python et mon script est sans doute mal écrit.

    Objectif : Faire rebondir une balle d'une hauteur de 200 px, px par px, avec un affichage toutes les 0,5 secondes (ce qui doit prendre 20 s)
    Remarque : J'ai ajouté une balle jaune pour visualiser la position initiale de la balle rouge et pour le moment la balle rouge se contente de monter pour que je puisse constater que ma fonction fonctionne.

    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
    "Importation des bibliothèques"
    from tkinter import *
     
    "Définition des fonctions"
    def deplacement(dy , nb): # Déplace balle1 "nb" fois de "dy" selon y
        global nb_aff
        while (nb_aff <= nb):
            nb_aff += 1
            Can.move(balle1,0,dy)
            Fen.after(500,deplacement(dy,nb))
     
    def rebond():
        nb_aff = 0
        deplacement(-1,200) # Déplace la balle1 de 200 px vers le haut de 1 px en 1 px
        #deplacement(1,200) # Déplace la balle1 de 200 px vers le bas de 1 px en 1 px
     
    Fen = Tk()
    Fen.title('Faire rebondir une balle')
     
    Can = Canvas(Fen , width = 400 , height = 300 , background = 'white')
    Can.pack()
    balle2 = Can.create_oval(40 , 280 , 60 , 300 , fill='yellow') # Balle fixe jaune
    balle1 = Can.create_oval(40 , 280 , 60 , 300 , fill='red') # Balle qui doit rebondir
    nb_aff = 0
    rebond()
     
    Fen.mainloop()
    Problème : La fenêtre nommée Fen ne s'affiche que lorsque la balle rouge a effectué son saut, enfin, que la première partie, c'est à dire après 10 s, or j'aimerais visualiser le déplacement de la bille rouge ...

    Je suis preneur de toute proposition même si le code est totalement revu.

    Par avance, merci.
    Je pense que ce code répondra à la problématique initiale il s'inspire grandement du post précédent

    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
     
    "Importation des bibliothèques"
    from tkinter import *
     
    "Définition des fonctions"
    def deplacement(dy , nb): # Déplace balle1 "nb" fois de "dy" selon y
        def _boucle():
            global nb_aff
            if nb_aff > nb:
                return
            nb_aff += 1
            Can.move(balle1,0,dy)
            Fen.after(500,_boucle)
     
        _boucle()
     
    def rebond():
        nb_aff = 0
        deplacement(-1,200) # Déplace la balle1 de 200 px vers le haut de 1 px en 1 px
        #deplacement(1,200) # Déplace la balle1 de 200 px vers le bas de 1 px en 1 px
     
    Fen = Tk()
    Fen.title('Faire rebondir une balle')
     
    Can = Canvas(Fen , width = 400 , height = 300 , background = 'white')
    Can.pack()
    balle2 = Can.create_oval(40 , 280 , 60 , 300 , fill='yellow') # Balle fixe jaune
    balle1 = Can.create_oval(40 , 280 , 60 , 300 , fill='red') # Balle qui doit rebondir
    nb_aff = 0
    rebond()
     
    Fen.mainloop()

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2018
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2018
    Messages : 3
    Par défaut
    Merci beaucoup pour votre aide.
    Au final, en m'inspirant des exemples du lien proposé, j'arrive à cette solution qui me convient :
    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
    "Importation des bibliothèques"
    from tkinter import *
     
    "Définition des fonctions"
    def deplacement(): # Déplacement de la balle
        global y, dy, flag
        y = y + dy
        if y ==80: # si on est au point le plus haut ...
            dy = -dy # ... on change de sens
        if y ==280: # si on arrive au niveau du sol ...
            flag = 0 # ... on stoppe le déplacement
        Can.coords(balle1 , 40 , y , 60 , y + 20)
        if flag >0:
            Fen.after(5,deplacement)
     
    def rebond():
        global flag, y, dy
        dy = -5 # La balle se déplace de 5 pixels en 5 pixels
        y = 280 # Ordonnée de départ
        flag = 1
        deplacement()
     
    Fen = Tk()
    Fen.title('Faire rebondir une balle')
     
    Can = Canvas(Fen , width = 400 , height = 300 , background = 'white')
    Can.pack()
    balle2 = Can.create_oval(40 , 280 , 60 , 300 , fill='yellow') # Balle fixe jaune
    balle3 = Can.create_oval(40 , 80 , 60 , 100 , fill='orange') # Balle fixe orange
    balle1 = Can.create_oval(40 , 280 , 60 , 300 , fill='red') # Balle qui doit rebondir
     
    rebond()
     
    Fen.mainloop()
    Par contre, je vais malgré tout tenter de comprendre la solution proposée ci-dessus afin de progresser encore ...
    Je ferme, le problème ayant trouvé sa solution.
    Encore merci.

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

Discussions similaires

  1. [Débutant] Faire rebondir une image
    Par kEep OnE dans le forum C#
    Réponses: 3
    Dernier message: 25/06/2011, 20h21
  2. [debutant] faire bouger une balle et une raquette problème
    Par jerem721 dans le forum Interfaces Graphiques en Java
    Réponses: 6
    Dernier message: 26/11/2007, 20h26
  3. [débutant]Faire appel à une action d'une ActionList
    Par petitours dans le forum C++Builder
    Réponses: 6
    Dernier message: 12/03/2004, 22h53
  4. Faire respecter une DTD !!!
    Par haypo dans le forum Valider
    Réponses: 3
    Dernier message: 12/07/2003, 19h20

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