Partage
  • Partager sur Facebook
  • Partager sur Twitter

Mon code ne fonctionne pas à tous les coups

Sujet résolu
    25 août 2014 à 14:33:28

    Bonjour, j'ai commencé à programmer un pong, seulement voilà tous les cinq points j'augmente la vitesse de la balle et à ce moment là mon code gérant la collision avec les raquettes ne fonctionne plus. Voici le code:

    collision = 0#vaut 1 si la balle touche la raquette1 ou 2 si elle touche la raquette2
    sortie = 0#vaut 0 si la balle n'est pas sortie 1 si c'est derriere la raquette 1 et 2 si c'est derriere la raquette 2
    
    
    
    #on modifie les positions de début et de fin des raquettes pour prendre en compte la taille de la balle
    pos_debut1 = [raquette1.pos_debut[0] + balle.taille_balle, raquette1.pos_debut[1] - balle.taille_balle]
    pos_debut2 = [raquette2.pos_debut[0] - balle.taille_balle, raquette2.pos_debut[1] - balle.taille_balle]
    
    
    pos_fin1 = [raquette1.pos_fin[0] + balle.taille_balle, raquette1.pos_fin[1] + balle.taille_balle]
    pos_fin2 = [raquette2.pos_fin[0] - balle.taille_balle, raquette2.pos_fin[1] + balle.taille_balle]
    
    
    #collision avec la raquette1
    if balle.pos >= pos_debut1 and balle.pos <= pos_fin1:
    	collision = 1
    
    
    #collision avec la raquette2
    elif balle.pos >= pos_debut2 and balle.pos <= pos_fin2:
    	collision = 2
    
    #gestion de la sortie
    if balle.pos[0] < pos_debut1[0] - balle.taille_balle * 2 - 60:
    	sortie = 1
    
    elif balle.pos[0] > pos_debut2[0] + balle.taille_balle * 2 + 60:
    	sortie = 2
    
    #si la balle touche le haut ou le bas on inverse le deplacement verticale
    if balle.pos[1] + deplacement[1] <= 0 + balle.taille_balle or balle.pos[1] + deplacement[1] >= taille_h - balle.taille_balle:
    	deplacement[1] = -deplacement[1]#permet de n'inverser que le deplacement verticale
    
    #gestion du deplacement en fonction de la collision
    if collision != 0:
    	deplacement[0] = -deplacement[0]
    	pygame.mixer.Sound(son).play()
    

    Merci d'avance pour votre aide.

    -
    Edité par sofaman 25 août 2014 à 14:34:31

    • Partager sur Facebook
    • Partager sur Twitter
    P != NP
    Anonyme
      25 août 2014 à 16:41:05

      Salut, on n'a qu'un morceau de code, donc ça va être réponse aléatoire : il est possible que la vitesse soit trop grande et donc qu'en un pas de temps, la balle passe de part et d'autre de ta raquette sans que tu puisses détecter la collision.

      • Partager sur Facebook
      • Partager sur Twitter
        25 août 2014 à 18:13:03

        Merci pour ta réponse. De base la balle se déplace de 6 pixels verticalement et horizontalement mais même en mettant la vitesse à 5 pixels la collision ne marche plus. Je mets la boucle pricipale du jeu.

        #amplitude du deplacement de la balle et des raquettes en px
        deplacement = [-5,-5]
        deplacement_raquette = 8
        
        #scores des 2 joueurs
        score1 = 0
        score2 = 0
        
        #raquettes des 2 joueurs
        raquette1 = Raquette([60, taille_h / 2 - 35],[60, taille_h / 2 + 35])
        raquette2 = Raquette([taille_l -60, taille_h / 2 - 35],[taille_l - 60, taille_h / 2 + 35])
        
        balle = Balle(taille_l / 2, taille_h / 2, 12)
        
        continuer = True
        
        collision = False
        
        sortie = 0
        
        pos_finale = 0#hauteur a laquelle sera la balle lorsqu'elle frappera la raquette de l'ordi
        
        #varaibles servant a savoir si la touche est toujours enfoncee
        haut1 = False
        bas1 = False
        
        haut2 = False
        bas2 = False
        
        #niveau de l'ia
        difficulte = 16
        
        #son lors d'une collision
        son = load_sound("pong.wav")
        
        #delai de repetition quand la touche est enfoncee
        pygame.key.set_repeat(50,30)
        
        
        while continuer:
        	pygame.time.Clock().tick(30)#limitation de la boucle a 30 fps
        	
        #gestion des évènements
        				
        #gestion de l'ia				
        				
        	collision, sortie, deplacement = is_collision(balle, raquette1, raquette2, deplacement, taille_h, son)
        	
        	balle.deplacer(deplacement)
        	
        	
        	collision = 0
        		
        #update de la fenetre

        J'ai retiré tous les blocs de déplacement et de l'ia pour rendre le tout plus lisible.

        • Partager sur Facebook
        • Partager sur Twitter
        P != NP
        Anonyme
          25 août 2014 à 18:44:38

          De base la balle se déplace de 6 pixels verticalement et horizontalement mais même en mettant la vitesse à 5 pixels la collision ne marche plus.

          "De base" ? C'est-à-dire ? En vitesse normale ? Ou après accélération ? À partir de quelle vitesse ça foire ?

          J'ai retiré tous les blocs de déplacement et de l'ia pour rendre le tout plus lisible.

          Ouais, mais du coup il manque l'essentiel... Avec juste le code que tu as donné, on ne sait même pas comment la balle se déplace, on ne sait rien de sa position ni de celle des raquettes, etc. On n'est pas devins.

          • Partager sur Facebook
          • Partager sur Twitter
            25 août 2014 à 18:52:52

            Au début du jeu la balle à une vitesse de 6 pixels et mon code fonctionne aussi avec une vitesse de 3 pixels mais ce sont les deux seuls valeurs que j'ai testé et qui fonctionne. Je remets tout le code avec les blocs de déplacement du joueur et de l'ia ainsi que le bloc qui gére l'accélération de la balle. (Ce n'est pas très propre par endroit :p)
            while continuer:
            	pygame.time.Clock().tick(30)#limitation de la boucle a 30 fps
            	for event in pygame.event.get():
            	
            		if event.type == QUIT:
            			sys.exit(0)
            
            		if event.type == KEYDOWN:
            			
            			if event.key == K_ESCAPE:
            				continuer = False
            			
            			if event.key == K_UP or haut1 and not bas1 :
            				raquette1.deplacer(-deplacement_raquette, taille_h)
            				haut1 = True
            				
            			if event.key == K_DOWN or bas1 and not haut1:
            				raquette1.deplacer(deplacement_raquette, taille_h)
            				bas1 = True
            
            
            		if event.type == KEYUP:
            			
            			if event.key == K_UP:
            				haut1 = False
            			
            			if event.key == K_DOWN:
            				bas1 = False
            
            				
            				
            				
            	collision, sortie, deplacement = is_collision(balle, raquette1, raquette2, deplacement, taille_h, son)
            	
            	balle.deplacer(deplacement)
            	
            	#GESTION DE L'IA
            	if collision == 1 or sortie == 2:
            		pos_finale = ia(balle, [deplacement[0], deplacement[1]], taille_h, taille_l, sortie, difficulte)
            	
            	if pos_finale >= raquette2.pos_debut[1] + 35:#si la balle est en dessous de la raquette2
            		haut2 = False
            		bas2 = True
            		
            	if pos_finale <= raquette2.pos_debut[1] + 35:#si la balle est au dessus de la raquette2
            		haut2 = True
            		bas2 = False
            		
            	if ceil(pos_finale/10) == ceil((raquette2.pos_debut[1] + 35)/10):
            		haut2 = False
            		bas2 = False
            		
            	#deplacement de l'ia
            	if haut2 and not bas2:
            		raquette2.deplacer(-deplacement_raquette, taille_h)
            		
            	if bas2 and not haut2:
            		raquette2.deplacer(deplacement_raquette, taille_h)
            	
            	
            	
            	collision = 0
            		
            	fenetre_update(fenetre, taille_l, taille_h, balle, raquette1, raquette2, score1, score2, (taille_l/2-38, 40), (taille_l/2+19, 40))
            
            		
            	#gestion des scores et de l'accélération de la balle tous les 5 points
            	if sortie != 0:
            		
            		
            		balle.pos = [taille_l / 2, taille_h / 2]
            		
            		if sortie == 1:
            			score1 += 1
            			
            		else:
            			score2 += 1	
            		if score1 % 5 == 0 and score1 != 0 or score2 % 5 == 0 and score2 != 0:
            			if deplacement[0] > 0:
            				deplacement[0] += 3
            				
            			else:
            				deplacement[0] -= 3
            				
            			if deplacement[1] > 0:
            				deplacement[1] += 3
            				
            			else:
            				deplacement[1] -= 3
            	
            	
            	
            	if score1 == 11 or score2 == 11:
            
            		fenetre_update(fenetre, taille_l, taille_h, balle, raquette1, raquette2, score1, score2, (taille_l/2-38, 40), (taille_l/2+19, 40))
            		afficher_text(fenetre, "Press Enter to continue", (taille_l / 2 * (len("Press enter to continue") / 2), taille_h/2))
            		
            		
            		while continuer:
            			
            			for event in pygame.event.get():
            			
            				if event.type == KEYDOWN:
            				
            					if event.key == K_RETURN:
            						continuer = False
            				if event.type == QUIT:
            
            					exit(0)
            

            -
            Edité par sofaman 25 août 2014 à 19:01:34

            • Partager sur Facebook
            • Partager sur Twitter
            P != NP
            Anonyme
              25 août 2014 à 19:21:17

              Ouais, enfin avec ça je suis pas bien plus avancé, je ne sais toujours pas quelles sont les positions de tes objets au cours du temps, puisque je n'ai pas les positions de départs (qui ont l'air d'être définies dans le constructeur).

              En tout cas, avec cette info en plus :

              la balle à une vitesse de 6 pixels et mon code fonctionne aussi avec une vitesse de 3 pixels

              ça a tout l'air de confirmer ma toute première hypothèse. Si tu as par exemple une raquette située en (x,36) et que ta balle part de (0,0) il faudra que la vitesse de la balle divise 36 pour que la balle soit située sur la raquette à un moment donné. Ainsi, la balle rencontre la raquette au bout de 12 pas de temps si la vitesse est 3, au bout de 6 pas de temps si la vitesse est 6, jamais si la vitesse est 5 (la balle va passer de 35 à 40, donc traverser la raquette sans que tu détectes la collision).

              Pour contrer ça, il suffit que la vitesse d'update de position soit grande devant celle de la balle pour que la balle ne se déplace pas de plus d'un pixel par pas de temps et que tu puisses détecter suffisamment finement sa position.

              • Partager sur Facebook
              • Partager sur Twitter
                25 août 2014 à 19:31:07

                Mais il reste un probleme : c'est que les raquettes sont à 60 pixels du bord. Mais si je mets la vitesse de la balle à 5 pixels et passe quand même à travers de la raquette donc je pense pas que le problème vienne de là.

                 Et pour les positions des objets j'avais oublié de remettre le code la deuxième fois.

                #les raquettes font 70 pixels 35 au dessus et 35 au dessous du milieu de l'écran
                raquette1 = Raquette([60, taille_h / 2 - 35],[60, taille_h / 2 + 35])
                raquette2 = Raquette([taille_l -60, taille_h / 2 - 35],[taille_l - 60, taille_h / 2 + 35])
                
                balle = Balle(taille_l / 2, taille_h / 2, 12)
                



                • Partager sur Facebook
                • Partager sur Twitter
                P != NP
                Anonyme
                  25 août 2014 à 19:47:58

                  Mais il reste un probleme : c'est que les raquettes sont à 60 pixels du bord

                  Et alors ? Ce qui compte, c'est la position absolue de la raquette dans le repère que tu utilises, pas celle du bord par rapport à la raquette. Franchement, mets le code complet, de façon à ce qu'il soit testable, parce que sinon, on va pas s'en sortir.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    25 août 2014 à 21:19:17

                    "ça a tout l'air de confirmer ma toute première hypothèse"

                    Je pense comme @drien. Ça doit être un problème de multiple entre le déplacement de ta balle et la position de la raquette. Par contre, au lieu de mettre tout ton code, je te conseillerai de prendre un peu de recul et d'essayer d'isoler le bout de code qui selon toi pose problème (apparemment ici c'est soit le déplacement, soit la condition qui vérifie la collision (ou soit les 2)). Parce que il est facile de se perdre avec tous ces taille_l - 60, taille_h/2 - 35, (raquette2.pos_debut[1] + 35)/10, etc... Aussi essaie (dans un autre fichier, et sans utiliser pour l'instant pygame) de simuler le déplacement de ta balle et de vérifier ta condition. Par exemple:

                    balle = [0, 0]
                    
                    while True:
                        balle[0] += 3
                        print(balle) #vérifie les coordonnées de la balle
                    
                        if balle[0] == 60:
                            break

                    ATTENTION:  ce code n'a aucun rapport avec le tien. C'est juste pour l'exemple. Mais c'est comme ça qu'on fait. On isole la partie qui nous semble "défectueuse" et on utilise des print pour vérifier le comportement.



                    • Partager sur Facebook
                    • Partager sur Twitter
                    Précepte: Le mieux est l'ennemi du bien
                      25 août 2014 à 22:23:34

                      Je sais exactement quel est le code qui pose problème c'est la condition qui vérifie la collision avec la raquette puisque la balle rebondi toujours sur les paroies. Je m'étais aussi fait la réfléxion que la balle "passait au travers" alors pour contrer ça j'avais fait une condition qui comparé d'abords la position x puis la position y et en prenant en compte le deplacement de la balle mais toujours le meme problème.

                      EDIT : je viens de trouver une autre source au problème : la taille de la balle. Elle est de 12 pixels de rayon qui est multiple de 3 et de 6 mais pas de 9 ni de 5 ce qui fait que la bale passe au trevers de la raquette.

                      -
                      Edité par sofaman 25 août 2014 à 22:32:52

                      • Partager sur Facebook
                      • Partager sur Twitter
                      P != NP
                      Anonyme
                        25 août 2014 à 22:25:42

                        Je m'étais aussi fait la réfléxion que la balle "passait au travers" alors pour contrer ça j'avais fait une condition qui comparé d'abords la position x puis la position y mais exactement le meme problème.

                        Je ne comprends pas comment c'était censé régler ton problème...

                        EDIT : ah ok.

                        Tant que tu ne seras pas décidé à nous donner plus d'infos sur la valeur des positions initiales, on ne pourra pas t'aider plus que ça.

                        -
                        Edité par Anonyme 25 août 2014 à 22:26:56

                        • Partager sur Facebook
                        • Partager sur Twitter
                          25 août 2014 à 22:54:22

                          Qu'est-ce que tu veux dire pare les positions initiales ? Les valeurs au début du jeu ?
                          • Partager sur Facebook
                          • Partager sur Twitter
                          P != NP
                          Anonyme
                            25 août 2014 à 22:59:12

                            Qu'est-ce que tu veux dire pare les positions initiales ? Les valeurs au début du jeu ?

                            Oui.

                            • Partager sur Facebook
                            • Partager sur Twitter
                              26 août 2014 à 0:52:18

                              La balle est placée au milieu du terrain soit en 390;240 et les raquettes s'étendent de 425;60 à 355;60 et 425;720 à 355;720 en clair le milieu des raquettes est à 60 pixels du coté et au milieu verticalement.
                              • Partager sur Facebook
                              • Partager sur Twitter
                              P != NP
                                26 août 2014 à 11:42:03

                                pourquoi la balle se déplace si vite ?
                                • Partager sur Facebook
                                • Partager sur Twitter

                                Python c'est bon, mangez-en. 

                                  26 août 2014 à 11:42:05

                                  "Je m'étais aussi fait la réflexion que la balle "passait au travers""

                                  C'est sur ce point que tu dois réfléchir. Comment as-tu pris en compte la collision? Juste en ne considérant qu'un point de la balle (par exemple le côté supérieur gauche) ou considère-tu la balle en entière? C'est bien évidemment de la dernière façon qu'il faut faire. Il faut considérer que si une partie de la balle touche une partie de la raquette, alors il y a collision. Voici un exemple console de ça:

                                  #Format des coordonnées: [x1, y1, x2, y2], avec (x1, y1) et (x2, y2): 2 points
                                  #bien choisis pour couvrir la surface totale de chaque objet.
                                  #c_r: coordonnées de la raquette
                                  #c_b: coordonnées de la balle
                                  c_r = [80, 10, 120, 10]
                                  c_b = [90, 0, 93, 3]
                                  
                                  
                                  #Un petit compteur pour afficher juste les 15 premiers tour de boucle
                                  compteur = 0
                                  while compteur < 15:
                                  
                                      #On augmente de 1 chaque ordonnée de la balle: On a un déplacement vertical
                                      c_b[1] += 1
                                      c_b[3] += 1
                                  
                                      #RAPPEL
                                      #Un set() est un objet de base de python. C'est un conteneur (comme les
                                      #listes, dico, etc...), et l'une de ses particularité c'est qu'il ne peut
                                      #pas avoir 2 objets identiques (par exemple il ne pourra pas y avoir 2 fois
                                      #le chiffre 5, ou 2 fois le mot "zero")
                                  
                                      #Ici c'est l'étape importante.
                                      #inter_x et inter_y représentent les coordonnees communes des 2 objets:
                                      inter_x = set(range(c_b[0], c_b[2]+1)).intersection(range(c_r[0], c_r[2]+1))
                                      inter_y = set(range(c_b[1], c_b[3]+1)).intersection(range(c_r[1], c_r[3]+1))
                                  
                                      #set(range(c_b[0], c_b[2]+1)):
                                      #On met l'intervalle des abscisses de la balle dans un set
                                  
                                      #.intersection(range(c_r[0], c_r[2]+1))
                                      #intersection() est une méthode de la classe set() qui renvoie les objets
                                      #communs entre 1 set et un itérable. Ici on a mis comme itérable
                                      #l'intervalle des abscisses de la raquette.
                                  
                                      #On fait la même chose avec les ordonnées de la balle et de la raquette
                                  
                                      #Si la partie abscisse ET la partie ordonnée de chaque objet ont des
                                      #positions communes, alors il y a collision et on affiche les coordonnées
                                      if  inter_x and inter_y:
                                          print()
                                          print("collision")
                                          print((inter_x, inter_y))
                                          print()
                                  
                                      #On affiche ce que contient inter_x et inter_y
                                      else:
                                          print((inter_x, inter_y))
                                  
                                      #Augmente le tour de boucle
                                      compteur += 1


                                  Mais il me semble que pygame a un système intégré de gestion des collisions. Tu devrais plutôt chercher de ce côté.

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Précepte: Le mieux est l'ennemi du bien
                                    26 août 2014 à 12:07:04

                                    josmiley a écrit:

                                    pourquoi la balle se déplace si vite ?


                                    Simplement parce que sinon le jeu est beaucoup trop lent.

                                    "Mais il me semble que pygame a un système intégré de gestion des collisions. Tu devrais plutôt chercher de ce côté."

                                    Je pense que je vais aller voir, mais le problème c'est que mon anglais ne permet pas de tout comprendre et je n'avais rien trouvé de concluant en français.

                                    Sinon merci quand même car je ne connaissais pas la méthode instersection pour les set.

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    P != NP
                                      26 août 2014 à 12:21:55

                                      Je viens de faire quelques recherches sur le système de collision de pygame et je me suis rappelé qu'au début du projet je voulais l'utiliser mais il ne s'applique qu'à des images et je n'en utilise pas.(désolé pour le double post)

                                      -
                                      Edité par sofaman 26 août 2014 à 12:26:18

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      P != NP
                                        26 août 2014 à 13:28:19

                                        Il n'y a pas d'image en pygame (il me semble). Il y a des Surface() et des Rect(). Quel est le type de ta raquette et de ta balle?

                                        -
                                        Edité par Olygrim 26 août 2014 à 13:29:11

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Précepte: Le mieux est l'ennemi du bien
                                          26 août 2014 à 13:51:10

                                          "Sinon le jeu est trop lent ..."

                                          C'est un problème de conception. 

                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          Python c'est bon, mangez-en. 

                                            26 août 2014 à 14:53:49

                                            mes raquettes et ma balle sont des fromes dessinées par pygame. 

                                            "C'est un problème de conception" euh non ou alors je vois pas en quoi. La balle se déplace de 6 pixels à toutes les frames donc 30x par seconde.

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                            P != NP
                                              26 août 2014 à 15:27:49

                                              Une frame n'équivaut pas forcement à un cycle de calcul.
                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              Python c'est bon, mangez-en. 

                                                26 août 2014 à 16:35:47

                                                Dans mon cas c'est le nombre de cycle de calcul par seconde
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                P != NP
                                                  26 août 2014 à 16:40:25

                                                  Et tu ne veux pas tenter une autre approche, en séparant l'affichage du reste ? Ce qui permettrait d'avancer d'un pixel à la fois et résoudrait ton problème. 

                                                  -
                                                  Edité par josmiley 26 août 2014 à 16:42:19

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter

                                                  Python c'est bon, mangez-en. 

                                                    26 août 2014 à 17:07:13

                                                    Je ne suis pas contre mais je sais pas comment faire. Si tu peux me donner quelques pistes je suis preneur.
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    P != NP
                                                      26 août 2014 à 17:37:28

                                                      Par exemple tu peux limiter la boucle principale à 180 cycles par seconde et n'afficher les images que tous les 6 cycles(soit 30 foid par seconde).

                                                      -
                                                      Edité par josmiley 26 août 2014 à 17:45:26

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter

                                                      Python c'est bon, mangez-en. 

                                                        26 août 2014 à 18:26:54

                                                        Même si ta solution semblait prometteuse, elle ne résout que paritellement le problème : quand j'augmente la vitesse de la balle arrive un moment où la taille de la balle n'est plus un multiple de la vitesse ce qui fait que la balle traverse la raquette. Donc la solution de Olygrim est la plus adaptée.

                                                        Merci beaucoup pour votre aide.

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        P != NP
                                                          26 août 2014 à 19:08:41

                                                          "mes raquettes et ma balle sont des formes dessinées par pygame. "

                                                          Il faut bien comprendre ce que tu as en sortie quand tu utilise une méthode ou une classe. Si tu as dessiné tes raquettes et ta balle avec le module draw de pygame, chaque fonction de ce module renvoie un objet Rect(). Tu peux donc normalement utilisé les méthodes pour gérer les collisions, qui sont justement des méthodes de la classe Rect().

                                                          import pygame
                                                          
                                                          #Regarde bien. Chaque fonction renvoie: -> Rect()
                                                          help(pygame.draw)
                                                          
                                                          #Les méthodes de collisions sont dans la classe Rect()
                                                          dir(pygame.Rect)
                                                          
                                                          #Par contre je ne m'en suis jamais servie.



                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                          Précepte: Le mieux est l'ennemi du bien
                                                            26 août 2014 à 19:35:58

                                                            Le fait est que mes objets ne sont pas des Rect, ils contiennent juste les coordonnées des objets qui eux sont dessinés quand je mets l'affichage à jour.
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                            P != NP
                                                            Anonyme
                                                              26 août 2014 à 19:37:21

                                                              Le fait est que mes objets ne sont pas des Rect, ils contiennent juste les coordonnées des objets qui eux sont dessinés quand je mets l'affichage à jour.

                                                              C'est pour ça que c'est lent, entre autre... :-°

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              Mon code ne fonctionne pas à tous les coups

                                                              × 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