Lag dans mon projet PyGame
RésoluMEZIANE002 -
Bonjour, je suis en train de créer un petit logiciel qui a pour vocation de m'aider à la conception de mon RPG, le problème est qu'il lagge affreusement après un certain nombre de cellules à l'écran. Si l'on crée un tableau de 10 par 10, ça va encore mais mon jeu utilise des maps d'au moin 32 par 18 et là c'est inutilisable. Merci de votre aide. Voilà mon code :
import pygame def display_text(text,w,font,color,screen,position): screen.blit(pygame.font.SysFont(font,w).render(text,True, color), position) def bordure(rect, e, screen): b1 = pygame.Rect((rect.x, rect.y), (e, rect.h)) b2 = pygame.Rect((rect.x+rect.w-e, rect.y), (e, rect.h)) b3 = pygame.Rect((rect.x, rect.y), (rect.w, e)) b4 = pygame.Rect((rect.x, rect.y+rect.h-e), (rect.w, e)) pygame.draw.rect(screen, (0,0,0), b1) pygame.draw.rect(screen, (0,0,0), b2) pygame.draw.rect(screen, (0,0,0), b3) pygame.draw.rect(screen, (0,0,0), b4) class Cellule: def __init__(self, x, y, elm, t): self.x = x self.y = y self.elm = elm self.rect = pygame.Rect((x,y), (t,t)) def draw(self, screen, e, k): bordure(self.rect, e, screen) display_text(self.elm, k, "arial", (0,0,0), screen, (self.rect.x+self.rect.w/3, self.rect.y+self.rect.w/4)) def overlap(self): return self.rect.collidepoint(pygame.mouse.get_pos()) def is_clicked(self, bool=True): return pygame.mouse.get_pressed()[0] and self.overlap() and bool print("Bienvenue dans le Map Maker !") cmd=input("Dimensions de la Map : ") w,h = int(cmd.split()[0]), int(cmd.split()[1]) cmd=input("Taille des cellules : ") t = int(cmd) cmd=input("Eléments : ") l=[" "] l+=cmd.split() pygame.init() screen = pygame.display.set_mode((1000,600)) pygame.display.set_caption("Map Maker Pygame") n=0 m=[] for i in range(h): m.append([Cellule(t*j+20, t*i+80, 'X', t) for j in range(w)]) while True: mouse = not pygame.mouse.get_pressed()[0] for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() screen.fill((255,255,255)) selecteur = Cellule(430, 10, l[n], 60) selecteur.draw(screen, 3, 30) if selecteur.is_clicked(bool=mouse): if n != len(l)-1: n+=1 else: n=0 for i in m: for j in i: j.draw(screen, 2, t//2) pygame.display.flip()
- Lag informatique
- Le code ascii en informatique - Guide
- Pc qui lag - Guide
- Jargon informatique - Télécharger - Bureautique
- Que veut dire url en informatique - Guide
- Souris informatique - Guide
2 réponses
Salut,
Qu'est censé faire ton code ?
Il faudrait quand même utiliser des noms de variables correctes, parce que des w, h, t, l, n… Rendent un code difficile à lire…
Pour ma part, il n'y a pas de ralentissement probant.
Testé avec
# cmd=input("Dimensions de la Map : ") # w,h = int(cmd.split()[0]), int(cmd.split()[1]) # cmd=input("Taille des cellules : ") # t = int(cmd) # cmd=input("Eléments : ") # l=[" "] # l+=cmd.split() w = 32 h = 18 t = 25 l = tuple(chr(i) for i in range(97, 123))
Que se passe-t-il lorsque tu l'exécutes ?
Maintenant plutôt que de créer à chaque tour un objet Cellule, déclare-le avant la boucle, et passe la valeur textuelle lors du draw.
Ajoute aussi un objet Clock afin de réguler la vitesse d'exécution.
clock = pygame.time.Clock()
while True:
clock.tick(30)
# …
Ok, en regardant un peu les temps d'exécution, on voit que ce qui fait ralentir est ta fonction display_text, en initialisant la police avant, le lag n'est plus, donc je ne sais comment fonctionne SDL, mais j'imagine qu'il doit y avoir un accès disque chaque fois qu'un objet SysFont est instanciée et que rien n'est gardé en mémoire.
En changeant ainsi :
pygame.init() font_game = pygame.font.SysFont('Arial', 12) def display_text(text,w,font,color,screen,position): screen.blit(font_game.render(text,True, color), position)
Plus de souci.
Donc, revois la façon dont sont créées tes cellules, nul besoin de générer chaque fois une police, ni même les bordures, cela devrait être fait à l'instance, mettre le texte et bordure sur une surface et c'est tout.
Un exemple avec sprites.
import pygame class Cell(pygame.sprite.Sprite): def __init__(self, x, y, size, text): super().__init__() self._text = text self.image = pygame.Surface((size, size)).convert() self.image.fill((255, 255, 0)) self._image = self.image.copy() self.rect = self.image.get_rect() self.rect.topleft = x, y self.font = pygame.font.SysFont('mono', 10, True) self._text_draw() def _text_draw(self): text_surf = self.font.render(self._text, True, (0, 0, 0)).convert_alpha() center = self.rect.w / 2, self.rect.h / 2 self.image.blit(text_surf, text_surf.get_rect(center=center)) [A]property def text(self): return self._text text.setter def text(self, value): self._text = value self.image = self._image.copy() self._text_draw() pygame.init() screen = pygame.display.set_mode((800, 600)) screen.convert() display_group = pygame.sprite.Group() cells = [Cell(x, y, 24, 'X') for x in range(0, 600, 25) for y in range(0, 400, 25)] display_group.add(cells) clock = pygame.time.Clock() running = True while running: for evt in pygame.event.get(): if evt.type == pygame.QUIT: running = False screen.fill((0, 0, 0)) display_group.update() display_group.draw(screen) pygame.display.update() clock.tick(30) # Affichage FPS # print(clock.get_fps()) pygame.quit()
Tu peux mettre n'importe quoi sur l'image, les bordures, etc.
NB: le [A] est à remplacer par le @, car ccm l'interprète comme une adresse mail…
Bonjour, je ne suis pas sur d'avoir compris, concernant la clock, je l'ai fait et cela lag encore.