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 :

bloquage sur des détections de collisions pour des eléments create_oval


Sujet :

Tkinter Python

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 3
    Points : 2
    Points
    2
    Par défaut bloquage sur des détections de collisions pour des eléments create_oval
    Bonjour à tous,

    Je suis tout neuf dans la programmation de python et dans la programmation tout court. Depuis quel temps, je m'y suis mis mais là je bloque. Mon apprentissage je le réalise avec le livre de Gérard Swinnen(apprendre à programmer avec python).

    Je cherche à réaliser l'exercice 8.30., dans cet exercice des boules doivent se déplacer et si une collision survient entre les différentes boules ou contre les parois de la fenêtre, elles doivent rebondir en sens inverse.

    je cherche depuis un moment mais là je bloque donc j'ai mis mon code ci-dessous.

    je ne cherche pas une correction du code mais plus de nouvelles pistes me permettant de réfléchir différemment.(mon but étant de réaliser l'exercice).

    N'hésitez pas à me dire si je suis mal parti avec mon code, je précise que je n'ai pas sauté de chapitres donc je ne connais pas certaines notions comme les classes.

    En vous remerciant à bientôt.

    Patchoman

    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
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
     
    #! /usr/bin/env python
    # -*- coding: Latin-1 -*-
     
    from Tkinter import *
    from random import randrange
     
    def addBall():
        """Boucle permettant de créer 5 balles dont les caractérisques sont crées 
            par des variables globales"""
        i=0
        global ball, x, y, r, coul
        while i<len(ball):
            ball[i] = can.create_oval(x[i]-r, y[i]-r, x[i]+r, y[i]+r, fill=color[i])
            i += 1
     
    def controlCollision():
        global x, y, dx, dy, r, color
        a=0
        b=1
        while a < 5 :
            b=a+1
            while b < 5:
                print a, b, x[a], x[b], y[a], y[b], dx[a], dx[b], dy[a], dy[b], color[a], color[b]
                if x[a]+r >= x[b]-r and x[a]-r <= x[b]+r:
                    # si les coordonnées x de la première balle sont comprises entre
                    # celles de la deuxième balle
                    if y[a]+r < y[b]-r:
                        dy[a],dy[b]=-dy[a],-dy[b]
                        print"ok 1"
                    if y[a]-r > y[b]+r:
                        dy[a],dy[b]=-dy[a],-dy[b]
                        print"ok 2"
     
                elif y[a]+r >= y[b]-r and y[a]-r <= y[b]+r:
                    if x[a]+r < x[b]-r:
                        dx[a],dx[b]=-dx[a],-dx[b]
                        print"ok 3"
                    if x[a]-r > x[b]+r:
                        dx[a],dx[b]=-dx[a],-dx[b]
                        print"ok 4"
                b += 1
            a += 1
     
     
    def moveBall():
        global x, y, dx, dy, flag, r, ball
        j=0
        while j<len(ball):
     
        # déplacement horizontal :
            if x[j] > (400-r) :
                x[j]=(400-r)
                dx[j] = -dx[j]             # on inverse le déplacement
            if x[j] < r:
                x[j]=r
                dx[j] = -dx[j]             # on inverse le déplacement
            controlCollision()
            x[j] = x[j] + dx[j]
     
        # déplacement vertical (proportionnel à la vitesse)
            if y[j] > (250-r):
                y[j]=(250-r)
                dy[j] = -dy[j]             # on inverse le déplacement
            if y[j] < r:
                y[j]=r
                dy[j] = -dy[j]             # on inverse le déplacement
            controlCollision()
            y[j] = y[j] + dy[j]
     
        # on repositionne les balles une par une :
            can.coords(ball[j], x[j]-r, y[j]-r, x[j]+r, y[j]+r)
            j +=1
    #        print x
    #        print y
            print dx, color
        # ... et on remet ça jusqu'à plus soif :
        if flag > 0:
            fen.after(50,moveBall)
     
    def start():
        global flag
        flag = flag +1
        if flag == 1:
            addBall()
            moveBall()
     
    def stop():
        global flag
        flag =0
     
    # fenêtre graphique
        # liste de 5 coordonnées x et y + un diamètre pour création des balles 
    x= [30,370,200,30,370]
    y= [30,30,125,220,220]
    r= 10
        # pas des déplacements en x et y au hasard choisis de 5 à 10 pour chaque balle
    dx= [randrange(5,10),randrange(5,10),randrange(5,10),randrange(5,10),randrange(5,10)]
    dy= [randrange(5,10),randrange(5,10),randrange(5,10),randrange(5,10),randrange(5,10)]
    flag = 0 
    ball=[0]*5 # liste des balles (vides au départ)
    color=['red','blue','green','yellow','purple']
    compteur = 0
     
    fen = Tk()
    fen.title(' Balles et rebonds')
    can = Canvas(fen, width =400, height=250, bg="white")
    can.pack()
     
    Button(fen, text='Start', command =start).pack(side =LEFT, padx =10)
    Button(fen, text='Stop', command =stop).pack(side =LEFT)
    Button(fen, text='Quitter', command =fen.quit).pack(side =RIGHT, padx =10)
    score =Label(fen,text="Le score est de " + str(compteur))
    score.pack()
     
    fen.mainloop()

  2. #2
    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 patchoman,

    Le but est proche, c'est juste ton calcul de collision entre les balles et sa position dans le code qui est a revoir. Celui des bords fonctionne, autant regrouper tes tests non ? Dans cet exercice j'aurais vu cela à l'inverse de toi : Contrôler les collisions avant de bouger la balle.

    Bon code.

    Ps : De plus j'aurais mis le addBall dans le main et les balles dans un dico (du main donc) pour éviter les globals. Style dicball = [nomdelaballe (Ball[i] si tu veux) : tuple (x, y, couleur)]. Voir l'explication ici.
    Merci d'utiliser le forum pour les questions techniques.

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Tout d'abord merci de ta réponse PauseKawa.

    Premièrement, effectivement mettre la fonction addball() dans le corps principal a supprimé un effet indésirable, l'ajout de nouvelles balles quand j'appuyais à nouveau sur le bouton start.

    Deuxièmement, concernant les dico et tuples, ce sont des notions que je n'ai pas encore abordé dans le livre, à priori c'est dans le prochain chapitre donc pour l'instant je vais essayer de me débrouiller avec ce que je connais.

    Et finalement je vais approfondir l'idée de tester les collisions avant les déplacements.

    Ps : je suis un compatriote biterrois , je suis ravi de savoir que je suis pas tout seul dans cette ville à m'intéresser à python.

    Merci encore et à bientôt

    Patchoman

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    voilà j'ai réussi à réaliser l'exercice

    Voilà en gros pour le calcul des collisions, je cherche à déterminer la distance entre les deux balles considérées.

    J'utilise le théorème de Pythagore ce qui me permet d'utiliser les coordonnées "x et y" en même temps (ce qui me posait problème sur la version précédente)

    je détermine les côtés du triangle par une soustraction entre les coordonnées x de chaque balle et idem pour les coordonnées y.

    Les calcul négatifs sont (effet positif) éliminées par les carrés des nombres et ensuite la racine carrée de hypoténuse est comparée à 2 fois le diamètre.

    Puis j'utilise à nouveau les longueurs horizontales pour déterminer d'où viennent les balles et donc l'inversion de leur sens

    Voici mon code :

    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
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
     
    #################################
    #     -*- coding:Utf-8 -*-      #
    #                               #
    #         exercice 8.30         #
    #################################
     
    from Tkinter import *
    from random import randrange
    from math import sqrt
     
    def addBall():
        """Boucle permettant de créer 5 balles dont les caractérisques sont crées 
            par des variables globales"""
        i=0
        global ball, x, y, r, coul
        while i<len(ball):
            ball[i] = can.create_oval(x[i]-r, y[i]-r, x[i]+r, y[i]+r, fill=color[i])
     
            i += 1
     
    def moveBall():
        global x, y, dx, dy, flag, r, ball
        j=0
        k=0
        while j<len(ball):
     
    # détection des collisions entre balles :
            k=j+1
            # calcul de la distance entre les 2 balles par l'hypothénuse du triangle
            # formé par les deux paires de coordonnées
            while k<5:
                ab=x[j]-x[k]
                ab=ab**2
                bc=y[j]-y[k]
                bc=bc**2
                ac=sqrt(ab+bc)
            # si la longueur est inférieure à 2 fois le rayon il y a collision
            # on utilise les carrés des 2 longueurs pour savoir d'où vient la balle
                if ac < 2*r:
                    if ab>bc :
                        dx[j],dx[k] = -dx[j],-dx[k]
                    elif bc>ab :
                        dy[j],dy[k] = -dy[j],-dy[k]
                    elif bc==ab :
                        dx[j],dx[k] = -dx[j],-dx[k]
                        dy[j],dy[k] = -dy[j],-dy[k]
                k +=1
     
    # détection des collisions sur les parois :
            if x[j] > (400-r) :
                x[j]=(400-r)
                dx[j] = -dx[j]             # on inverse le déplacement
            if x[j] < r:
                x[j]=r
                dx[j] = -dx[j]             # on inverse le déplacement
        # déplacement horizontal :
            x[j] = x[j] + dx[j]
     
            if y[j] > (250-r):
                y[j]=(250-r)
                dy[j] = -dy[j]             # on inverse le déplacement
            if y[j] < r:
                y[j]=r
                dy[j] = -dy[j]             # on inverse le déplacement
        # déplacement vertical
            y[j] = y[j] + dy[j]
     
    # on repositionne les balles une par une :
            can.coords(ball[j], x[j]-r, y[j]-r, x[j]+r, y[j]+r)
            j +=1
        # ... et on remet ça jusqu'à plus soif :
        if flag > 0:
            fen.after(50,moveBall)
     
    def start():
        global flag
        flag = flag +1
        if flag == 1:
            moveBall()
     
    def stop():
        global flag
        flag =0
     
    # fenêtre graphique
        # liste de 5 coordonnées x et y + un diamètre pour création des balles 
    x= [30,370,200,30,370]
    y= [30,30,125,220,220]
    r= 10
        # pas des déplacements en x et y au hasard choisis de 5 à 10 pour chaque balle
    dx= [randrange(5,10),randrange(5,10),randrange(5,10),randrange(5,10),randrange(5,10)]
    dy= [randrange(5,10),randrange(5,10),randrange(5,10),randrange(5,10),randrange(5,10)]
    flag = 0 
    ball=[0]*5 # liste des balles (vides au départ)
    color=['red','blue','green','yellow','purple']
    compteur = 0
     
    fen = Tk()
    fen.title(' Balles et rebonds')
    can = Canvas(fen, width =400, height=250, bg="white")
    can.pack()
     
    Button(fen, text='Start', command =start).pack(side =LEFT, padx =10)
    Button(fen, text='Stop', command =stop).pack(side =LEFT)
    Button(fen, text='Quitter', command =fen.quit).pack(side =RIGHT, padx =10)
    score =Label(fen,text="Le score est de " + str(compteur))
    score.pack()
    addBall()
     
    fen.mainloop()
    Encore merci pour la réponse

    A bientôt

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

Discussions similaires

  1. Détection de pitchs pour des sons environnementaux
    Par Luke Kall dans le forum Algorithmes et structures de données
    Réponses: 0
    Dernier message: 18/05/2013, 15h50
  2. Réponses: 0
    Dernier message: 08/11/2011, 12h00
  3. Réponses: 6
    Dernier message: 04/06/2010, 21h17
  4. Réponses: 6
    Dernier message: 14/11/2007, 16h38
  5. Réponses: 3
    Dernier message: 08/06/2007, 13h26

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