Partage
  • Partager sur Facebook
  • Partager sur Twitter

POO : collision de deux balle.

    5 août 2010 à 7:44:02

    Bonjour à tous, j'ai crée un programme qui génère un canevas dans lequel des balles ricoche sur les parois et entres elles.

    Pour commencer j'ai fait simple: deux balles (une rouge et une bleu), la rouge va de droite à gauche et la bleu de haut en bas...

    Je les est programmé de sorte à ce qu'elle s'entrechoquent, le but est que la bleu ricoche sur la rouge (par exemple), mais au lieu de ça, elle va SUR la rouge :-°

    from tkinter import *
    
    # définition des gestionnaires
    # d'événements :
    
    
    
    
    
    def move():
        "déplacement de la balle"
        global x, y, dx, dy, flag
        x, y = x +dx, y + dy
        if (x > 90):
           x, dx  = 90, -15
        if (x < 10):
           x, dx  = 10, 15
    
        can1.coords(oval1,x,y,x+30,y+30)
        if flag >0: 
            fen1.after(30,move)       # => boucler après 50 millisecondes
    
    
    def move2():
        "déplacement de la balle"
        global x0, y0, dx0, dy0, flag
        x0, y0 = x0 +dx0, y0 + dy0
        if (y0 > 210):
           y0, dy0  = 210, -15
        if (y0 < 10):
           y0, dy0  = 10, 15
    
     
    
        can1.coords(oval2,x0,y0,x0+30,y0+30)
        if flag >0: 
            fen1.after(30,move2)
    
    def stop_it():
        "arret de l'animation"
        global flag
        flag =0
    
    def start_it():
        "démarrage de l'animation"
        
        global flag
        if flag ==0:       # pour ne lancer qu'une seule boucle 
           flag =1
           move()
           move2()
    
    #========== Programme principal =============
    
    # les variables suivantes seront utilisées de manière globale :
    x, y = 10, 10           # coordonnées initiales
    x0, y0 = 60, 200
    dx, dy = 15, 0          # 'pas' du déplacement
    dx0, dy0 = 0, 15
    flag =0                 # commutateur
    
    
    
    
    # Création du widget principal ("parent") :
    fen1 = Tk()
    fen1.title("Exercice d'animation avec Tkinter")
    # création des widgets "enfants" :
    
    
    can1 = Canvas(fen1,bg='dark grey',height=250, width=250)
    can1.pack(side=LEFT, padx =5, pady =5)
    
    oval1 = can1.create_oval(x, y, x+30, y+30, width=2, fill='red')
    oval2 = can1.create_oval(x0, y0, x+80, y+160, width=2, fill='blue')
    
    
    
    bou1 = Button(fen1,text='Quitter', width =8, command= fen1.destroy).pack(side=BOTTOM)
    bou2 = Button(fen1, text='Démarrer', width =8, command=start_it).pack()
    bou3 = Button(fen1, text='Arrêter', width =8, command=stop_it).pack()
    
    
    # démarrage du réceptionnaire d'évènements (boucle principale) :
    fen1.mainloop()
    




    J'ai essayé avec cette condition mais le résultat n'est pas celui attendu :
    if (can1.tag_bind(oval1)):
    
    • Partager sur Facebook
    • Partager sur Twitter
      5 août 2010 à 11:01:49

      Hmmm...
      J'ai pas trop le courage de rentrer dans ton code, mais pour ce qui est de la collision, étant donné que tu n'as que 2 balles, tu peux la gérer de manière "naïve" :
      si on note <math>\((x_1, y_1)\)</math> les coordonnées du centre de la première balle, <math>\((x_2, y_2)\)</math> celle du centre de la seconde balle, et <math>\(r_1, r_2\)</math> leurs rayons respectifs, alors les deux balles entrent en collision si la distance entre les centres des deux balles est inférieure ou égale à la somme de leurs rayons.

      <math>\(\sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}\ \leq\ r_1 + r_2\)</math>

      Pour ce qui est du calcul du rebond, en revanche, c'est un peu plus compliqué...
      • Partager sur Facebook
      • Partager sur Twitter
      Zeste de Savoir, le site qui en a dans le citron !
        7 août 2010 à 6:01:42

        Merci de ta réponse.

        J'ai essayé ta formule et apparemment ça marche...
        Seul problème, je n'arrive pas à utilisé la puissance deux... Je suis obligé de multiplier les parenthèse entre elles:


        if (sqrt (((x - x0))*((x - x0)) + ((y - y0))*((y - y0)) <= 30)):
        
        • Partager sur Facebook
        • Partager sur Twitter
          7 août 2010 à 12:54:26

          Petit conseil, étant donné que tu ne calcules cette distance que pour la comparaison, et que la fonction racine carrée est continue et strictement croissante, tu peux éviter d'appeler sqrt et travailler directement sur les valeurs carrées :

          if (x2 - x1)**2 + (y2 - y1)**2 <= (r2 + r1)**2:
              print 'collision !'
          
          • Partager sur Facebook
          • Partager sur Twitter
          Zeste de Savoir, le site qui en a dans le citron !

          POO : collision de deux balle.

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown