Partage
  • Partager sur Facebook
  • Partager sur Twitter

Probleme lag avec Pygame

    23 février 2016 à 21:08:04

    Bonjour a tous,

    Dans le cas de notre projet isn nous avons voulu créer un labyrinthe en python grace a pygame. Notre jeu fonctionne bien cependant il lag énormément et nous n'arrivons pas a régler ce problème. Voici le code de notre jeu : 

    import pygame
    import time
    from pygame.locals import *
    from pygame.draw import circle
    from Cartes import *
    pygame.init()
    Carte = Carte_1
    nombreCaseCote = len(Carte)
    tailleCase = 50
    tailleRond = 3000
    tailleRondBase = tailleRond
    StartAnimation = False
    PremiereAnimation = True
    #taille et ouverture de la fenêtre pygame
    tailleFenetre = nombreCaseCote * tailleCase
    fenetre = pygame.display.set_mode((tailleFenetre, tailleFenetre))
    
    #Chargement et collage du fond
    fond = pygame.Surface(fenetre.get_size()) #fond qui prend toute la fenêtre
    fond = fond.convert() 
    fond.fill((255,255,255))  #fond en blanc
    
    #Chargement et collage du personnage
    perso = pygame.transform.scale(pygame.image.load("perso.png").convert_alpha(),(tailleCase-15 ,tailleCase-15)) #charge la photo du perso, intègre le fonctionnement alpha et redimensionne
    position_perso = perso.get_rect()
    position_perso.topleft = 5,5 #http://www.pygame.org/docs/ref/rect.html
    fenetre.blit(perso, position_perso)
    
    cercle = pygame.transform.scale(pygame.image.load("Cercle_3_Compréssé.png").convert_alpha(),(tailleRond,tailleRond))
    position_cercle = cercle.get_rect()
    position_cercle.center = position_perso.center
    fenetre.blit(cercle,position_cercle)
    
    
    #Rafraîchissement de l'écran
    pygame.display.flip()
    
    #création d'un chrono
    touche = False
    minutes = 0
    seconds = 0
    milliseconds = 0
    font = pygame.font.Font ("freesansbold.ttf", 20)
    text = font.render("",True,(0,0,0))
    fenetre.blit(text, (300,300))
    start = 0
    
    imageMur = "mur.png"
    imageDepart = "depart.png"
    imageArrivee = "arrivee.png"
    BouclePrincipale = 1
    pygame.key.set_repeat(100, 100)#répétition touches directionnelles
           
    def afficher(fenetre):
            mur = pygame.transform.scale(pygame.image.load(imageMur).convert(),(tailleCase,tailleCase))
            depart = pygame.transform.scale(pygame.image.load(imageDepart).convert(),(tailleCase,tailleCase))
            arrivee = pygame.transform.scale(pygame.image.load(imageArrivee).convert(),(tailleCase,tailleCase))
            numeroLigne = 0
            for ligne in Carte:
                numeroCase = 0
                for case in ligne:
                    x = numeroCase * tailleCase
                    y = numeroLigne * tailleCase
                    if case == 'm':        
                        fenetre.blit(mur, (x,y))
                    elif case == 'D':        
                        fenetre.blit(depart, (x,y))
                    elif case == 'A':        
                        fenetre.blit(arrivee, (x,y))
                    numeroCase += 1
                numeroLigne += 1
                
              
    
    while BouclePrincipale:
        pygame.display.flip()
        afficher(fenetre)
    
        for event in pygame.event.get():
            if event.type == QUIT:
                BouclePrincipale = 0
                pygame.quit()
            if event.type == KEYDOWN:
                StartAnimation = True
                touche = True
                if event.key == K_DOWN:    #Si "flèche bas"
                    if position_perso.bottom < tailleFenetre-10:
                        if Carte[int((position_perso.y/tailleCase)+1)][int(position_perso.x/tailleCase)] != 'm':
                            position_perso = position_perso.move(0,tailleCase)
                if event.key == K_RIGHT:
                    if position_perso.right < tailleFenetre-10:
                        if Carte[int(position_perso.y/tailleCase)][int((position_perso.x/tailleCase)+1)] != 'm':
                            position_perso = position_perso.move(tailleCase,0)
                if event.key == K_LEFT:
                    if position_perso.left > 5:
                        if Carte[int(position_perso.y/tailleCase)][int((position_perso.x/tailleCase)-1)] != 'm':
                            position_perso = position_perso.move(-tailleCase,0)
                if event.key == K_UP:
                    if position_perso.top > 5:
                        if Carte[int((position_perso.y/tailleCase)-1)][int(position_perso.x/tailleCase)] != 'm':
                            position_perso = position_perso.move(0,-tailleCase)
        
        #chronomètre                   
        if touche == True:
            temps = time.time()-start
            seconds = int(temps)
            milliseconds = int((temps*1000))
            minutes = int((seconds - seconds%60)/60)
        else :
            start = time.time()
            
        #Lancer animation de la lumiere
        if tailleRond > tailleRondBase:
            tailleRond = tailleRond - 1000
        if PremiereAnimation == True:
                if StartAnimation == True:
                    if tailleRond == tailleRondBase:
                            tailleRond = 15000
                            PremiereAnimation = False
                            
        cercle = pygame.transform.scale(cercle,(tailleRond,tailleRond))                   
        text = font.render(str("{}:{}:{}".format(minutes,seconds%60,milliseconds%1000)), True, (250,250,250))    
        fenetre.blit(fond, (0,0))            
        afficher(fenetre)            
        fenetre.blit(perso, position_perso)
        position_cercle = cercle.get_rect()
        position_cercle.center = position_perso.center
        fenetre.blit(cercle, position_cercle)
        fenetre.blit(text,(tailleFenetre-85,5)) 
        if Carte[int((position_perso.y/tailleCase))][int(position_perso.x/tailleCase)] == 'A':   
            fenetre.blit(pygame.transform.scale(pygame.image.load("bravo.png").convert(),(tailleFenetre,tailleFenetre)),(0,0))
            touche = False
            font = pygame.font.Font ("freesansbold.ttf", 48)
            text = font.render(str("{}:{}:{}".format(minutes,seconds%60,milliseconds%1000)), True, (0,0,0))          
            fenetre.blit(text,(220,350))     
            for event in pygame.event.get():
                if event.type == KEYDOWN:
                    BouclePrincipale = 0 
        pygame.display.flip()
    

    Je precise de plus que au debut Carte = Carte_1 prend une liste très grande qui contient la carte du labyrinthe avec une liste des murs et des endroits ou on peut passer. 

    Merci !

    • Partager sur Facebook
    • Partager sur Twitter
      23 février 2016 à 23:06:59

      Faut pas recharger les images systématiquement ...
      • Partager sur Facebook
      • Partager sur Twitter

      Python c'est bon, mangez-en. 

        24 février 2016 à 9:51:56

        josmiley parle de la fonction afficher qui est appelée à chaque tour de boucle principale. Vous devez charger les images plus haut dans le code (vers la ligne 50 dans votre code présenté, et utiliser ces variables globales dans la fonction afficher.

        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          24 février 2016 à 15:46:43

          ni les textes systématique (sauf pour le décompteur de l'heure je pense). ceux qui sont statiques, tu les crées une seule fois, tu les stock dans une lsite / dico / plusieurs variables et hop. ca augmentera tes fps

          le coup du transform.scale à chaque tour de boucle ... c'est pas ce qu'il y  de meilleur. surtout que j'ai l'impression que le cerlce ne va pas changer de taille tout le temps. meme qu'il va changer de taille qu'une seule fois aussi. donc un truc en plus à ne pas faire dans ta boucle

          aussi, recréer une police, c'est pas ce qu'il y a de meilleur pour les perfs

          bonne chance pour votre projet ;)

          • Partager sur Facebook
          • Partager sur Twitter
            24 février 2016 à 15:57:12

            Merci beaucoup pour vos réponses je vais tester avec tout ce que vous m'avez conseillé et je vous redis après ce que ca donne :) Et j'ai essayé de mettre que une fois la fonction afficher mais le problème c'est que les cases n'apparaissent mais elle sont présentés quand meme 

            Voila ce que ca me fait en appelant qu'une fois la fonction cependant il y a des endroits ou on ne peut pas aller (la ou il y a les cases ) mais on ne voit pas de carré noir représentant les murs comme ci dessous : 

            -
            Edité par MathisD 24 février 2016 à 16:08:25

            • Partager sur Facebook
            • Partager sur Twitter
              24 février 2016 à 16:44:06

              MathisD a écrit:

              Et j'ai essayé de mettre que une fois la fonction afficher

              Toi tu as lu en diagonale... :/ J'ai jamais dit ne pas pas appeler la fonction afficher à chaque tour de boucle. J'ai dit que dans la fonction `afficher` tu ne dois pas charger les images ! Donc bouge juste les lignes 55-57 en dehors de la fonction afficher. Place-les en ligne 51. Et voilà !

              • Partager sur Facebook
              • Partager sur Twitter
                24 février 2016 à 16:57:23

                Ah oui en effet je m'en suis rendu compte désolé , mais c'est vrai que ca bug deja beaucoup moins ! Cependant quand il y a l'animation du cercle qui se dézoom mon jeu lag enormement encore :/
                • Partager sur Facebook
                • Partager sur Twitter
                Anonyme
                  24 février 2016 à 17:08:41

                  import pygame
                  import time
                  from pygame.locals import *
                  from Cartes import *
                  
                  
                  pygame.init()
                  Carte = Carte_1
                  nombreCaseCote = len(Carte)
                  tailleCase = 50
                  tailleRond = 3000
                  tailleRondBase = tailleRond
                  StartAnimation = False
                  PremiereAnimation = True
                  tailleFenetre = nombreCaseCote * tailleCase
                  fenetre = pygame.display.set_mode((tailleFenetre, tailleFenetre))
                  
                  #Chargement et collage du fond
                  fond = pygame.Surface(fenetre.get_size()) #fond qui prend toute la fenêtre
                  fond = fond.convert()
                  fond.fill((255,255,255))  #fond en blanc
                  
                  #Chargement et collage du personnage
                  perso = pygame.transform.scale(pygame.image.load("perso.png").convert_alpha(),(tailleCase-15 ,tailleCase-15)) #charge la photo du perso, intègre le fonctionnement alpha et redimensionne
                  position_perso = perso.get_rect()
                  position_perso.topleft = 5, 5
                  fenetre.blit(perso, position_perso)
                  
                  cercle = pygame.transform.scale(pygame.image.load("Cercle_3_Compréssé.png").convert_alpha(),(tailleRond,tailleRond))
                  position_cercle = cercle.get_rect()
                  position_cercle.center = position_perso.center
                  
                  #création d'un chrono
                  touche = False
                  minutes = 0
                  seconds = 0
                  milliseconds = 0
                  font = pygame.font.SysFont("freesansbold", 20)
                  bigfont = pygame.font.SysFont("freesansbold", 48)
                  start = 0
                  
                  imageMur = "mur.png"
                  imageDepart = "depart.png"
                  imageArrivee = "arrivee.png"
                  BouclePrincipale = 1
                  pygame.key.set_repeat(100, 100)  #répétition touches directionnelles
                  
                  mur = pygame.transform.scale(pygame.image.load(imageMur).convert(), (tailleCase, tailleCase))
                  depart = pygame.transform.scale(pygame.image.load(imageDepart).convert(), (tailleCase, tailleCase))
                  arrivee = pygame.transform.scale(pygame.image.load(imageArrivee).convert(), (tailleCase, tailleCase))
                  
                  
                  def afficher(fenetre):
                      numeroLigne = 0
                      for ligne in Carte:
                          numeroCase = 0
                          for case in ligne:
                              x = numeroCase * tailleCase
                              y = numeroLigne * tailleCase
                              if case == 'm':
                                  fenetre.blit(mur, (x, y))
                              elif case == 'D':
                                  fenetre.blit(depart, (x, y))
                              elif case == 'A':
                                  fenetre.blit(arrivee, (x, y))
                              numeroCase += 1
                          numeroLigne += 1
                  
                  
                  while BouclePrincipale:
                      for event in pygame.event.get():
                          if event.type == QUIT:
                              BouclePrincipale = 0
                              pygame.quit()
                          if event.type == KEYDOWN:
                              StartAnimation = True
                              touche = True
                              if event.key == K_DOWN:    #Si "flèche bas"
                                  if position_perso.bottom < tailleFenetre-10:
                                      if Carte[int((position_perso.y/tailleCase)+1)][int(position_perso.x/tailleCase)] != 'm':
                                          position_perso = position_perso.move(0,tailleCase)
                              if event.key == K_RIGHT:
                                  if position_perso.right < tailleFenetre-10:
                                      if Carte[int(position_perso.y/tailleCase)][int((position_perso.x/tailleCase)+1)] != 'm':
                                          position_perso = position_perso.move(tailleCase,0)
                              if event.key == K_LEFT:
                                  if position_perso.left > 5:
                                      if Carte[int(position_perso.y/tailleCase)][int((position_perso.x/tailleCase)-1)] != 'm':
                                          position_perso = position_perso.move(-tailleCase,0)
                              if event.key == K_UP:
                                  if position_perso.top > 5:
                                      if Carte[int((position_perso.y/tailleCase)-1)][int(position_perso.x/tailleCase)] != 'm':
                                          position_perso = position_perso.move(0,-tailleCase)
                       
                      #chronomètre
                      if touche == True:
                          temps = time.time() - start
                          seconds = int(temps)
                          milliseconds = int((temps * 1000))
                          minutes = int((seconds - seconds % 60) / 60)
                      else :
                          start = time.time()
                           
                      #Lancer animation de la lumiere
                      if tailleRond > tailleRondBase:
                          tailleRond = tailleRond - 1000
                      if PremiereAnimation == True:
                          if StartAnimation == True:
                              if tailleRond == tailleRondBase:
                                  tailleRond = 15000
                                  PremiereAnimation = False
                      
                      cercle = pygame.transform.scale(cercle, (tailleRond, tailleRond))
                      text = font.render(str("{}:{}:{}".format(minutes, seconds % 60, milliseconds % 1000)), True, (250, 250, 250))
                      position_cercle = cercle.get_rect()
                      position_cercle.center = position_perso.center
                      fenetre.blit(fond, (0, 0))
                      afficher(fenetre)
                      fenetre.blit(perso, position_perso)
                      fenetre.blit(cercle, position_cercle)
                      fenetre.blit(text, (tailleFenetre - 85, 5))
                      
                      if Carte[int((position_perso.y/tailleCase))][int(position_perso.x/tailleCase)] == 'A':
                          fenetre.blit(pygame.transform.scale(pygame.image.load("bravo.png").convert(),(tailleFenetre,tailleFenetre)), (0, 0))
                          touche = False
                          text = bigfont.render(str("{}:{}:{}".format(minutes, seconds % 60, milliseconds % 1000)), True, (0, 0, 0))
                          fenetre.blit(text, (220, 350))
                          
                          event = pygame.event.poll()
                          if event.type == QUIT:
                              BouclePrincipale = 0
                      
                      pygame.display.flip()

                  Et encore, pour l'animation du cercle je mettrais bien ça dans un dico, mais comme je suis pas sûr de bien comprendre ce que tu veux faire ...

                  (oui parce qu'au moins dans le dico ce sera chargé une seule et unique fois)

                  (sinon tu peux faire un loader jit)

                  • Partager sur Facebook
                  • Partager sur Twitter
                    24 février 2016 à 17:39:25

                    Merci pour le code il marche bien et je savais pas comment enlever la police ;) 

                    Pour le rond je voudrais que quand j'avance pour la premiere fois le rond s'agrandisse et que l'on voit la carte en entier puis il rétréci pour revenir a sa taille initiale pour mettre de la difficulté au jeu (taille initiale étant celle de l'image ci dessous 

                     

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Anonyme
                      26 février 2016 à 19:21:29

                      Le rond ne s’agrandit qu'une fois ? Si oui, ne le fait qu'une fois dans ce cas, et avant d'entrer dans la boucle de jeu ;)
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Probleme lag avec Pygame

                      × 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