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

Python Discussion :

Problème de rebonds et de collisions sur des balles


Sujet :

Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Lyceen
    Inscrit en
    Novembre 2012
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lyceen
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2012
    Messages : 40
    Points : 18
    Points
    18
    Par défaut Problème de rebonds et de collisions sur des balles
    Bonjour,

    Je suis actuellement en train d'essayer de coder un programme permettant de faire rebondir plusieurs balles sur des parois tout en gérant les collisions.

    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    # --- Importer les bibliothèques utilisées ---- #
    import tkinter as tk    # pour Python 2.x, c'est Tkinter (majuscule initiale)
    import random
    import time
     
    # --- Variables  --- #
     
    w_fen, h_fen = 500, 400 # Dimensions de notre zone graphique.
    balle = int(input("Choisissez le nombre de balles"))
    x = [random.randint(0,500) for i in range(balle+1)] # Position x aléatoire des balles.
    y = [random.randint(0,400) for i in range(balle+1)] # Position y aléatoire des balles.
    r = 8 # ayon de la balle.
    n = 0 # Variable compteur.
    dx = [random.randint(-5,5) for i in range(balle+1)] # Etape 4 : Rebond aléatoire.
    dy = [random.randint(-5,5) for i in range(balle+1)] # Etape 4 : Rebond aléatoire.
    drapeau = True
    Couleur = ["Red","Yellow","Gray","White","Black","Blue","Green","Orange","Pink"]
     
    while n != balle : # Empecher d'avoir le 0 comme valeur et ainsi empecher un non mouvement possible d'une balle.
        if dx[n] == 0 or dy[n] == 0 :
            dx = [random.randint(-5,5) for i in range(balle+1)] # Etape 4 : Rebond aléatoire.
            dy = [random.randint(-5,5) for i in range(balle+1)] # Etape 4 : Rebond aléatoire.
            n = - 1
        n = n + 1
    n = 1
     
     
     
    # --- Fonctions de modification de l'interface graphique --- #
    def fin(event=None):
        "Fin anticipée (Maj+Ctrl+Fin)."
        fen.destroy()
    # Etape 3 : Touche <Return> et <Space>
    def arret(event=None): # Arret des mouvements a l'appui de la touche Entree.
        global drapeau
        drapeau = True
    def reprise(event=None): # Reprise des mouvements a l'appui de la touche Espace.
        global drapeau
        drapeau = False
    def cercle(x, y, r, nom = n): #Fonction cercle
        a = x - r
        b = y - r
        c = x + r
        d = y + r 
        return can.create_oval((a,b,c,d), fill=Couleur[NbCouleur], outline="black", tag = nom)
     
    # --- Fenêtre principale --- #
    fen = tk.Tk()           # Crée la fenêtre principale de l'application.
    fen.title("Boules & Billes...")
     
    tit = tk.Label(fen, text="Boules & Billes :")       # Un petit titre...
    tit.pack(side=tk.TOP)
     
    can = tk.Canvas(fen)    # Puis une surface 'pour dessiner' à l'intérieur.
    can.configure(width=w_fen, height=h_fen, bg='white')
    can.pack(side=tk.TOP)
     
    # --- COMMANDES --- # 
    boutQuit=tk.Button(fen, text="Quitter", command=fin).pack(side=tk.BOTTOM)
    fen.bind("<Shift-Control-End>", fin)
    fen.bind("<Return>",arret)
    fen.bind("<space>",reprise)
     
    # --- PARTIE PRINCIPALE DU CODE --- #
     
    while n!=balle +1 : # Affichage des cercles un a un.
        NbCouleur = random.randint(0,8)
        cercle(x[n],y[n],r) 
        n = n + 1
    n = 1 # Remise de n a 0 pour commencer le mouvement des balles une par une.
    while 1:
        while drapeau == False :
            fen.update()
        while drapeau == True : # Boucle infinie.
     
            # --- GESTION DU MOUVEMENT --- #
            can.move(n,dx[n],dy[n]) # Déplacement de la balle selon dx et dy.
            fen.update()  # Actualisation de la fenetre graphique.
            fen.after(3) # Vitesse de la balle.
     
            # --- GESTION DES REBONDS SUR LES BORDS --- #
            if 500 - r < x[n] < 500 + r or -r < x[n] < r : # Si la balle touche le bord en x ...
                dx[n] = -dx[n] # Gestion du rebord en prenant l'inverse de dx pour un rebond coherent.
            if 400 - r < y[n] < 400 + r or -r < y[n] < r : # Si la balle touche le bord en y ...
                dy[n] = -dy[n] # Gestion du rebord en prenant l'inverse de dy pour un rebond coherent.
            y[n] = y[n] + dy[n] # Incrementation de dy sur y.
            x[n] = x[n] + dx[n] # Incrementation de dx sur x.
     
            if n == (balle): # Si on a fait bouger toute les balles une fois ... 
                n = -1 # ... On reinitialise n pour recommencer une boucle.
            n = n + 1
            col = 1
     
     
    # ------------------------------------ #
     
    fen.mainloop()
    Je suis entrain de chercher comme mieux gérer les rebonds sur les parois pour commencer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if x[n] + dx[n] > 500 - 5 :
                    can.move(n,(500-dx[n]-r),0)
                    fen.upload()
                    fen.after(10)
                    x[n] = x[n] + (500-dx[n]-r)
                    dx[n] = -dx[n]
    J'avais penser a quelques choses du style.
    Seulement, au début de mon programme, j'ai utilisé une magouille en faisant les randoms sur (balle + 1) et non balle car ma fonction can.move ne veut pas bouger ma balles "0". Je suis donc contraint de générer une balles de plus pour avoir le nombres voulu, ce qui fait qu'il y a une pair de coordonnée générer aléatoirement en trop.
    Ceci entraînant des problèmes dans la suite du programme et faussant totalement mes rebonds sur les parois ainsi que mes essaies de collisions.

    J'ai trouver un début de formule pour la gestion des collisions :
    En gros la conditions serait la suivante.
    (x[col] serait les collisions des balles tester une par une contre la balles [n])

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    while n != col :
                    if x[n] + ((x[col]-x[n])/2) = x[col] - ((x[col]-x[n])/2) :
                                    "Gestion de mouvement après collisions"
                    col = col + 1
    Pourriez vous m'aider a résoudre ses problèmes ? Je reste ouvert a une discussion via Mp ou Skype si nécessaire.

    Bromy

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,
    Seulement, au début de mon programme, j'ai utilisé une magouille en faisant les randoms sur (balle + 1) et non balle car ma fonction can.move ne veut pas bouger ma balles "0". Je suis donc contraint de générer une balles de plus pour avoir le nombres voulu, ce qui fait qu'il y a une pair de coordonnée générer aléatoirement en trop.
    Vous avez créé une association de 1..N vers les listes x, y, dx, dy pour laquelle à tt n dans 1..N, les x[n], y[n], dx[n], dy[n] sont les positions et déplacements de la balle n.

    Pourquoi ne pas créer la liste Balles qui serait remplie par la fonction cercle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def cercle(x, y): #Fonction cercle
        a = x - r     # r est une variable globale non?
        b = y - r
        c = x + r
        d = y + r 
        iid = can.create_oval((a,b,c,d), fill=Couleur[NbCouleur], outline="black")
        Balles.append(iid)
    => virez les '+1' dans les range(balles+1)

    Maintenant on a une liste d'identifiants de Balles une association de 0..(N-1) vers les listes Balles, x, y, dx, dy pour laquelle: à tt n dans 0..N-1, les Balles[n], x[n], y[n], dx[n], dy[n] sont identifiant, position et déplacement de la balle n.

    Simplification de la boucle de déplacement des balles:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    while drapeau:
        for n, iid in enumerate(Balles): # récupération de l'index et de l'identifiant
             can.move(iid,dx[n],dy[n]) # Déplacement de la balle selon dx et dy.
             ...
         #detection des collisions
             ...
         #traitement des collisions
             ... 
        fen.update()  # Actualisation de la fenetre graphique.
        fen.after(3) # Vitesse de la balle.
    Le principe étant de faire un déplacement sur l'ensemble toutes les 3 unités de temps => pas la peine de le faire pour chaque balle.

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

  3. #3
    Membre à l'essai
    Homme Profil pro
    Lyceen
    Inscrit en
    Novembre 2012
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lyceen
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2012
    Messages : 40
    Points : 18
    Points
    18
    Par défaut
    Merci bien je vais regarder.

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    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 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Plutôt que d'avoir n balles, puis n positions, puis n directions en x et en y, pourquoi ne pas carrément créer un objet balle qui embarquerait ses caractéristiques ?
    Ensuite ne resterait qu'à générer n balles puis à les faire évoluer. Coté visu cela ne changerait rien mais ça rendrait le code bien plus lisible et évolutif (les balles pourraient ensuite avoir des tailles et des vitesses différentes par exemple...)

    Citation Envoyé par bromy Voir le message
    Seulement, au début de mon programme, j'ai utilisé une magouille en faisant les randoms sur (balle + 1) et non balle car ma fonction can.move ne veut pas bouger ma balles "0". Je suis donc contraint de générer une balles de plus pour avoir le nombres voulu, ce qui fait qu'il y a une paire de coordonnées générées aléatoirement en trop.
    Là je n'ai rien compris. Je lis "la fonction que j'ai créé refuse (???) de traiter la balle 0 donc je la laisse faire tranquillement sa rebelle sans m'en inquiéter plus que ça..."
    Déjà si une fonction ne fait pas ce que je veux, ben chez-moi elle ne le fait pas longtemps et rentre vite fait dans le rang.
    Surtout que pour moi "0" n'est qu'un nombre parmi d'autres et n'a aucune caractéristique particulière (hormis que c'est le seul à ne pouvoir diviser aucun nombre mais cela n'entre pas vraiment en ligne de compte ici...)
    Bref je pense ici à quelque chose de mal pensé. Quoi qu'il en soit, "magouiller" (pour éviter de réfléchir ?) n'amène jamais rien de bon à long terme (la preuve...)

    PS: ce serait bien que tu fasses attention à tes accords (infinitif/participe passé/genre/nombre...)
    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]

  5. #5
    Membre à l'essai
    Homme Profil pro
    Lyceen
    Inscrit en
    Novembre 2012
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lyceen
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2012
    Messages : 40
    Points : 18
    Points
    18
    Par défaut
    Je pense que corriger les fautes n'est pas forcement utile, je trouve que ça rabaisse la personne.
    Pour me justifier, même si je n'en trouve pas l’utilité, je possède un clavier américain sans accents, donc pour les conjugaisons, soit je copie les accents un a un, soit j'utilise l'auto correction lorsque je le peux.

    Pour en revenir a mon programme, j'ai eu beau étudier les solutions proposées, ma faible expérience dans le langage Python m’empêche de bien comprendre.

    De plus,

    Quoi qu'il en soit, "magouiller" (pour éviter de réfléchir ?) n'amène jamais rien de bon à long terme (la preuve...)
    Encore une fois, je ne veux pas créer des tensions, mais lorsque l'on passe un certain temps a chercher, et que rien n'y fait, on perd en motivation il faut avouer
    Donc oui, j'ai "magouiller", après avoir fait des schémas sur feuilles, des calcules sur feuilles, des tests, lu la docs ...

    Bref, merci pour ton message, ça motive a poster...
    M'enfin, apparemment je me suis tromper de forum, c'est pour les professionnels ici si j'ai bien compris. Je n'y suis donc pas a ma place.

  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 684
    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 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par bromy Voir le message
    Je pense que corriger les fautes n'est pas forcement utile, je trouve que ça rabaisse la personne.
    Moi je trouve que bien écrire est une marque de respect envers la personne qui me lira, pour lui éviter de lagguer à relire 3 fois la ligne parce que le sens des mots va à l'encontre du sens probable de la phrase...

    Citation Envoyé par bromy Voir le message
    Pour me justifier, même si je n'en trouve pas l’utilité, je possède un clavier américain sans accents, donc pour les conjugaisons, soit je copie les accents un a un, soit j'utilise l'auto correction lorsque je le peux.
    Effectivement c'est pas facile. Mais on ne peut pas le deviner surtout que le petit drapeau à coté de ton pseudo indique que tu es en France...

    Citation Envoyé par bromy Voir le message
    Pour en revenir a mon programme, j'ai eu beau étudier les solutions proposées, ma faible expérience dans le langage Python m’empêche de bien comprendre.
    L'ignorance est de courte durée, la connaissance reste à vie. Tu n'es pas obligé de comprendre de suite, l'important est que tu saches que c'est possible pour y revenir plus tard. Moi j'ai suivi en début de semaine un stage administration avancée Postgres de 3 jours ben j'en ai chié. Maintenant, je reprends les TP un à un plus tranquillement...

    Citation Envoyé par bromy Voir le message
    Encore une fois, je ne veux pas créer des tensions, mais lorsque l'on passe un certain temps a chercher, et que rien n'y fait, on perd en motivation il faut avouer
    Donc oui, j'ai "magouiller", après avoir fait des schémas sur feuilles, des calcules sur feuilles, des tests, lu la docs ...
    As-tu mis des "print" pour afficher tes valeurs ???

    Citation Envoyé par bromy Voir le message
    Bref, merci pour ton message, ça motive a poster...
    Ou alors tu réfléchis au delà de l'impression initiale et tu te dis que si on te houspille un peu c'est parce qu'on se soucie de toi. On te montre des directions, des possibilités...

    Citation Envoyé par bromy Voir le message
    M'enfin, apparemment je me suis tromper de forum, c'est pour les professionnels ici si j'ai bien compris. Je n'y suis donc pas a ma place.
    Non, c'est pour tout le monde (pourvu qu'ils s'intéressent vraiment et soient prêts à s'investir un peu parce que sinon ça ne nous motive pas non plus à nous investir nous aussi). Mais comme bien évidemment ce sont des professionnels qui te répondront (parce qu'ils ont l'expérience eux), tu auras fatalement des réponses de pros (mais éprouvées et fonctionnelles, elles)...
    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
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Citation Envoyé par Sve@r Voir le message
    Là je n'ai rien compris. Je lis "la fonction que j'ai créé refuse (???) de traiter la balle 0 donc je la laisse faire tranquillement sa rebelle sans m'en inquiéter plus que ça..."
    Déjà si une fonction ne fait pas ce que je veux, ben chez-moi elle ne le fait pas longtemps et rentre vite fait dans le rang.
    Surtout que pour moi "0" n'est qu'un nombre parmi d'autres et n'a aucune caractéristique particulière (hormis que c'est le seul à ne pouvoir diviser aucun nombre mais cela n'entre pas vraiment en ligne de compte ici...)
    Sans doute pour la bonne raison que l'id 0 n'existe pas mais que l'entier 0 est accepté.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    can.move(n,dx[n],dy[n])
    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
    from tkinter import *
     
     
    def Callback():
        can.itemconfig("0", fill="yellow")
        can.itemconfig("1", fill="green")
     
     
    fen = Tk()
    can = Canvas(fen)
    can.pack()
    ov = can.create_oval(150, 150, 200, 200, fill='red', tags="0")
    print(ov)
    fen.after(1500, Callback)
    fen.mainloop()
    @+
    Merci d'utiliser le forum pour les questions techniques.

  8. #8
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 813
    Points : 7 102
    Points
    7 102
    Par défaut
    +1 à tout ce qu'a dit Sve@r, pour motiver un aidant, il faut rendre son post le plus attractif, détaillé possible.

    Petite parenthèse, mais qui a son importance, certains seront d'accord, d'autres non, mais jouer avec Tkinter sur quelques lignes, à la rigueur ça me dérange pas, mais lorsqu'on commence à rentrer dans le cadre du code plus conséquent, l'avantage de python c'est la POO (Programmation Orientée Objet).

    Dans ton cas, le code que tu as créés sera vite illisible tant par les lecteurs que par toi même (ce qui est plus grave).

    Citation Envoyé par bromy
    Je suis actuellement en train d'essayer de coder un programme permettant de faire rebondir plusieurs balles
    Plusieurs balles, c'est plusieurs objets, donc classe Balle instanciée plusieurs fois...

    D'ailleurs pour citer Sve@r, cette question est restée sans réponse

    Citation Envoyé par Sve@r
    pourquoi ne pas carrément créer un objet balle qui embarquerait ses caractéristiques ?
    Second point, même si c'est possible de le faire avec Tkinter, je ne pense pas que se soit le plus adapté pour faire ce genre de chose, je pense plus à pygame par exemple (il y en a d'autres).

    Conclusion : Même si Tkinter est simple, les bases python sont nécessaires, et j'ajouterais la POO avec tout ça...
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  9. #9
    Membre à l'essai
    Homme Profil pro
    Lyceen
    Inscrit en
    Novembre 2012
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lyceen
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2012
    Messages : 40
    Points : 18
    Points
    18
    Par défaut
    Yop,
    Pour l'objet balle qui embarquerait ses caractéristiques, pourrais tu développer un petit peu ?
    Pygame à l'air bien, mais deux raisons m'empêche de l'utiliser.
    La premier étant que je n'ai pas réussi à l'installer, j'ai eu beau essayer de desinstaller 5 fois pythons, essayer de 30 manières différentes et même de suivre des tutos.
    Mais la deuxième reste la plus contraignante, je fais ce programme dans le cadre scolaire => on a pas pygame, seulement tkinter qui est installé par défaut.

    Je répond depuis mon iPhone et je n'ai pas encore pu tester ce que vous avez proposé.
    Bon week

  10. #10
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 813
    Points : 7 102
    Points
    7 102
    Par défaut
    Citation Envoyé par bromy
    Pour l'objet balle qui embarquerait ses caractéristiques, pourrais tu développer un petit peu ?
    Avec un code exemple, c'est mieux non?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Balle:
        def __init__(self, color, x, y, r):
            self.color = color
            self.x, self.y = x, y
            self.rayon = r
        # fonctions représentant les actions de la balle
     
    ma_balle = Balle("Red", 12, 5, 10)
    # traitement de ma_balle ...
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    S'il est intéressant (intellectuellement) qu'une balle soit associée à l'instance d'une classe Balle, il n'est pas interdit de construire ses balles en gérant leurs différents attributs dans différentes listes.

    Le soucis est dans la construction de la correspondance entre l'ovale affiché dans le canvas et l'index correspondant de ces listes:
    • l'index d'une liste commencera par 0,
    • l'identifiant d'un objet du canvas sera toujours >= 1.


    Sachant que les identifiants des objets crées dans le canvas sont attribués dans l'ordre, la "magouille" consistant à ignorer l'élément d'indice 0 des listes fonctionne pour peu qu'on gère l'exception.

    Une autre approche est d'ajouter la liste des identifiants des "oval" crées par le canvas. Il n'y a plus d'exception et on peut envisager le .delete et la création de nouvelles balles.

    Si le PO n'est pas capable de la mettre en oeuvre, c'est probablement qu'il n'a pas encore acquis les bases de la programmation Python. Mais s'il ne donne pas les difficultés qu'il rencontre difficile de l'aider.

    En tout cas, raconter que la librairie graphique ou l'approche retenue par le PO ne sont pas au top de ce qu'on peut faire avec Python et au raz des pâquerettes côté POO...

    Certes, mais on dirait que vous avez oublié que vous aussi étiez débutants.
    En quoi dire au PO qu'il est nul va l'aider à faire fonctionner son programme ou à progresser dans son apprentissage de la programmation.

    Quel est l'intérêt de proposer une classe Balle en faisant complètement l'impasse sur la gestion de la correspondance entre les instances de balles et les ovales crées dans le canvas?
    Cette correspondance est quand même le sujet du post, non?
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  12. #12
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bref... Tout ceci est bien inutile pour le po.

    Un petit coup de main au po, sur son code.
    Il lui resteras pas mal a voir surtout ce while... snif... ).

    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    import tkinter as tk    # pour Python 2.x, c'est Tkinter (majuscule initiale)
    from random import randint
     
     
    # --- Variables et constantes --- #
    balle = int(input("Choisissez le nombre de balles"))
     
    # Création des listes de valeurs.
    x = [randint(0, 500) for i in range(balle)]  # Position x aléatoire des balles.
    y = [randint(0, 400) for i in range(balle)]  # Position y aléatoire des balles.
    dx = [randint(-5, 5) for i in range(balle)]  # Etape 4 : Rebond aléatoire.
    dy = [randint(-5, 5) for i in range(balle)]  # Etape 4 : Rebond aléatoire.
    w_fen = 500
    h_fen = 400
    r = 8  # Rayon de la balle.
    drapeau = True
    Couleur = ["Red", "Yellow", "Gray", "White", "Black", "Blue", "Green", "Orange", "Pink"]
    Balles = []
     
    # --- Fonctions de modification de l'interface graphique --- #
    def fin(event=None):
        "Fin anticipée (Maj+Ctrl+Fin)."
        fen.destroy()
     
    # Etape 3 : Touche <Return> et <Space>
    def arret(event=None): # Arret des mouvements a l'appui de la touche Entree.
        global drapeau
        drapeau = True
     
    def reprise(event=None): # Reprise des mouvements a l'appui de la touche Espace.
        global drapeau
        drapeau = False
     
     
    # --- Fenêtre principale --- #
    fen = tk.Tk()  # Crée la fenêtre principale de l'application.
    fen.title("Boules & Billes...")
    tit = tk.Label(fen, text="Boules & Billes :")  # Un petit titre...
    tit.pack()
    can = tk.Canvas(fen, width=w_fen, height=h_fen, bg='white')  # Puis une surface 'pour dessiner' à l'intérieur.
    can.pack()  # Pas besoin de side ici, ni plus bas.
    # --- COMMANDES --- # 
    boutQuit = tk.Button(fen, text="Quitter", command=fin).pack()
    fen.bind("<Shift-Control-End>", fin)
    fen.bind("<Return>", arret)
    fen.bind("<space>", reprise)
     
    # --- PARTIE PRINCIPALE DU CODE --- #
    # Création des 'balles'
    for idx in range(balle): # Affichage des cercles un a un.
        NbCouleur = randint(0, 8)
        a = x[idx] - r
        b = y[idx] - r
        c = x[idx] + r
        d = y[idx] + r
        Balles.append(can.create_oval((a, b, c, d), fill=Couleur[NbCouleur], outline="black"))
     
    while 1:
        if drapeau: # Boucle infinie.
     
            # --- GESTION DU MOUVEMENT --- #
            for n in range(balle):
                can.move(Balles[n], dx[n], dy[n])  # Déplacement de la balle selon dx et dy.
                fen.update()  # Actualisation de la fenetre graphique.
                fen.after(3)  # Vitesse de la balle.
     
                # --- GESTION DES REBONDS SUR LES BORDS --- #
                if 500 - r < x[n] < 500 + r or -r < x[n] < r: # Si la balle touche le bord en x ...
                    dx[n] = -dx[n]  # Gestion du rebord en prenant l'inverse de dx pour un rebond coherent.
                if 400 - r < y[n] < 400 + r or -r < y[n] < r:  # Si la balle touche le bord en y ...
                    dy[n] = -dy[n]  # Gestion du rebord en prenant l'inverse de dy pour un rebond coherent.
                y[n] = y[n] + dy[n]  # Incrementation de dy sur y.
                x[n] = x[n] + dx[n]  # Incrementation de dx sur x.
     
     
    # ------------------------------------ #
     
    fen.mainloop()
    Edit :
    Ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
         for n, iid in enumerate(Balles): # récupération de l'index et de l'identifiant
             can.move(iid,dx[n],dy[n])
    AU choix. L'index dans les listes reste le même.
    Merci d'utiliser le forum pour les questions techniques.

  13. #13
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 813
    Points : 7 102
    Points
    7 102
    Par défaut
    Citation Envoyé par wiztricks
    Certes, mais on dirait que vous avez oublié que vous aussi étiez débutants.
    Tu n'as pas dû comprendre le sens de ma phrase.

    Quand je parle de POO, je parle que travailler sur Tkinter avant de comprendre la POO semble trop rapide et la lisibilité du code s'en ferait ressentir.

    Maintenant il est pas interdit de faire sans et je stipule bien

    Citation Envoyé par fred1599
    Petite parenthèse, mais qui a son importance, certains seront d'accord, d'autres non, mais jouer avec Tkinter sur quelques lignes, à la rigueur ça me dérange pas, mais lorsqu'on commence à rentrer dans le cadre du code plus conséquent, l'avantage de python c'est la POO (Programmation Orientée Objet).
    Je me doutais bien que tout le monde ne serait pas d'accord

    Citation Envoyé par wiztricks
    En quoi dire au PO qu'il est nul
    Je ne pense pas être visé ou il faut me dire où j'ai fais comprendre au PO qu'il était nul...

    Citation Envoyé par wiztricks
    Si le PO n'est pas capable de la mettre en oeuvre, c'est probablement qu'il n'a pas encore acquis les bases de la programmation Python. Mais s'il ne donne pas les difficultés qu'il rencontre difficile de l'aider.
    Pour cela que mon code n'est pas complet car je pense bien qu'il n'est pas capable de le faire, simplement je lui fais comprendre qu'apprendre la POO pourrait avoir ses avantages dans ce genre d'exercice.

    Citation Envoyé par wiztricks
    Quel est l'intérêt de proposer une classe Balle en faisant complètement l'impasse sur la gestion de la correspondance entre les instances de balles et les ovales crées dans le canvas?
    Cette correspondance est quand même le sujet du post, non?
    • Manque de temps
    • On a parlé d'un exemple sur les caractéristiques de la balle
    • Aucun intérêt car le PO ne connaissant pas la POO, ne sera pas utiliser la classe
    • Ne pas faire tout le travail


    Enfin bref c'était des conseils, pas des insultes, n'exagérons rien...
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  14. #14
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    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 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Avec un code exemple, c'est mieux non?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Balle:
        def __init__(self, color, x, y, r):
            self.color = color
            self.x, self.y = x, y
            self.rayon = r
        # fonctions représentant les actions de la balle
     
    ma_balle = Balle("Red", 12, 5, 10)
    # traitement de ma_balle ...
    Juste pour montrer une suite possible...

    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
    class Balle:
        def __init__(self, color, x, y, r):
            self.color = color
            self.x, self.y = x, y
            self.rayon = r
     
        def move(self, x, y):
            self.x=self.x+x
            self.y=self.y+y
     
        def isOver(self):
            return self.x < limiteXmin or self.x > limiteXmax\
            or self.y < limiteYmin or self.y > limiteYmax
     
         def isCollision(self, other):
             return self.x == other.x and self.y == other.y
             # Pour bien faire faudra gérer le diamètre (équations du cercle etc) mais c'est juste pour illustrer
     
         def __str__(self):
             return "balle[%s]- position %d/%d" % (
                   self.color,
                   self.x,
                   self.y,
             )
    # class Balle
     
    ma_balle = Balle("Red", 12, 5, 10)
    ma_balle.move(3, 2)
    print ma_balle   # Appellera automatiquement la méthode "__str__"
    # + d'autres traitements...
    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]

  15. #15
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Le code de notre PO est difficile à lire, ce n'est pas parce qu'il n'a pas mis le pied dans la POO mais plutôt parce qu'il ne sait pas encore "structurer" son code.

    Structurer le code passe par la création de fonctions qui regroupe un ensemble d'opérations cohérentes.
    Par exemple, pourquoi créer les tableaux positions et delta pour toutes les balles plutôt que de cacher cela dans la fonction cercle?
    Il est vrai aussi que variables globales et constantes mériteraient d'être plus différenciées: x, y,... pour ces tableaux c'est pas top.

    On pourrait tout regrouper ainsi:
    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
    # Constantes
    WIDTH, HEIGHT = 500, 400
    RADIUS = 8
    COLORS = ["Red","Yellow","Gray","White","Black","Blue","Green","Orange","Pink"]
     
     
    # variables globales
    canvas = None
    balles = []
    deltas = []
    positions = []
     
    def balle_create():
        randint = random.randint
        x = randint(RADIUS, WIDTH-RADIUS)
        y = randint(RADIUS, HEIGHT-RADIUS)
        color = random.choice(COLORS)
        iid = canvas.create_oval(x - RADIUS, y - RADIUS, 
                                  x + RADIUS, y + RADIUS,
                                 fill = random.choice(COLORS),
                                 outline='black',
                                 tag='balle')
        d = RADIUS//2
        deltas.append( (randint(-d, d), randint(-d, d)) )
        positions.append( (x, y) )
        balles.append(iid)
    Les actions principales de "l'application" sont simples:
    1. saisie du nombre de balles,
    2. lancement de tk,
    3. creation des balles,
    4. lancement du mouvement,
    5. attente de la fin

    On pourrait regrouper tout cela dans une fonction ou en utilisant le truc Python suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if __name__ == '__main__':
        nb_balles = int(input('nombre de balles: '))
     
        root = tk.Tk()
        root.title('Boules & Billes')
        canvas = tk.Canvas(width=WIDTH, height=HEIGHT, bg='white')
        canvas.pack(fill=BOTH)
        for _ in range(nb_balles):
            balle_create()
        motion()
        tk.mainloop()
    Reste à adapter "motion" (plutôt qu'un while planté au milieu de nulle part...) à ces nouvelles structures de données:
    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
    DELAY = 50
    def motion():
        x_min, x_max = RADIUS, WIDTH - RADIUS
        y_min, y_max = RADIUS, HEIGHT - RADIUS
     
        for n, iid, in enumerate(balles):
            dx, dy = deltas[n]
            canvas.move(iid, dx, dy) 
            x, y = positions[n]
            if not (x_min < x < x_max):
                dx = -dx
            if not(y_min < y < y_max):
                dy = -dy
            positions[n] = (x + dx, y + dy)
            deltas[n] = (dx, dy)
     
        canvas.after(DELAY, motion)
    A défaut de marcher mieux, c'est sans doute plus lisible... et si c'est plus lisible, ce sera plus simple à améliorer.


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

  16. #16
    Membre à l'essai
    Homme Profil pro
    Lyceen
    Inscrit en
    Novembre 2012
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lyceen
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2012
    Messages : 40
    Points : 18
    Points
    18
    Par défaut
    Plop,

    Y'a beaucoup de contenu x) C'est cool.
    J'vais tester tout ça !
    Juste un truc qui m'intrigue, PO signifie ?

    Autre chose, lorsque je lance mon prog, l'input se lance, me demande le nombre de balle voulu, et ensuite, la fenêtre graphique ne s'affiche pas en premier plan, il y a un truc a faire ?

  17. #17
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    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 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par bromy Voir le message
    Juste un truc qui m'intrigue, PO signifie ?
    Posteur Originel (toi donc) ; à ne pas confondre avec POO (Programmation Orientée Objet)...
    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]

  18. #18
    Membre à l'essai
    Homme Profil pro
    Lyceen
    Inscrit en
    Novembre 2012
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lyceen
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2012
    Messages : 40
    Points : 18
    Points
    18
    Par défaut
    J'avais compris le sens, je chercher juste la signification, merci

  19. #19
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Citation Envoyé par bromy Voir le message
    Autre chose, lorsque je lance mon prog, l'input se lance, me demande le nombre de balle voulu, et ensuite, la fenêtre graphique ne s'affiche pas en premier plan, il y a un truc a faire ?
    Ne s'affiche pas ou pas en premier plan ?
    Si c'est ne s'affiche pas c'est que vous avez encore votre while et plus de update().
    Sinon pour le premier plan c'est fen.wm_attributes("-topmost", 1)

    A voir avec du code.

    @+
    Merci d'utiliser le forum pour les questions techniques.

  20. #20
    Membre à l'essai
    Homme Profil pro
    Lyceen
    Inscrit en
    Novembre 2012
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lyceen
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2012
    Messages : 40
    Points : 18
    Points
    18
    Par défaut
    C'est bien le fait que la fenêtre ne s'affiche pas en premier plan.

Discussions similaires

  1. Réponses: 2
    Dernier message: 19/02/2014, 09h27
  2. problème au passage de la souris sur des onglets
    Par mimmolette dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 18/12/2010, 15h22
  3. Collision sur des nombres aléatoires
    Par sliderman dans le forum Requêtes
    Réponses: 4
    Dernier message: 03/07/2009, 12h55
  4. Réponses: 2
    Dernier message: 18/02/2009, 14h16
  5. Problème d'attribut de lecture seule sur des dossiers
    Par Redbull dans le forum Sécurité
    Réponses: 2
    Dernier message: 09/08/2005, 09h52

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