Jeu qui ramme affreusement (PyGame)
Résolu
MEZIANE002
-
MEZIANE002 -
MEZIANE002 -
Bonjour, je code un rpg sur Pygame, au début il fonctionne bien, mais après quelques secondes il commence à Ramer, j'aimerais savoir quelle est la source du problèle, merci.
Voila le fichier main.py
import pygame from essentiels import * #Initialisation élémentaire pygame.init() c=1 d=[(1920, 1080), (1280, 720), (1360, 768)] l,h=d[c] screen = pygame.display.set_mode((l,h)) fps = 60 game=0 menu_=0 mouse = True #Bouttons du Menu play = Template((l/2,h/4+h/6), 270) ecran = Template((l/2, (5*h)/12+h/6), 270) quitter = Template((l/2, (5*h)/12+(2*h/6)), 270) resolution = Template((l/2,h/4), 270) pl_ecran = Template((l/2, (5*h)/12), 270) menu = Template((l/2, (5*h)/12+h/6), 270) #Initialisation du Niveau et du Joueur joueur = Player((l/2, h/2), (50,50)) niveau = Tileset(["XXXXXXXXXXXXX", "X X", 'X XXX X', "XX XX", "X X", "XXXX XXXXXX"], {"X" : (120,120,120)}, (50,50),0,0) #Boucle de Jeu while True: mouse = not pygame.mouse.get_pressed()[0] for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() pygame.time.Clock().tick(fps) l,h=d[c] if game == 0: screen.fill((0,20,0)) display_text("Zelda, La Quête de la liberté", 100,"arial" ,(255,220,220), screen, (15,40)) play.draw_button("Jouer", screen) ecran.draw_button("Ecran", screen) quitter.draw_button("Quitter", screen) if ecran.is_clicked(bool=mouse): game=1 mouse=False if quitter.is_clicked(bool=mouse): pygame.quit() exit() if play.is_clicked(bool=mouse): game=2 if game == 1: screen.fill((0,20,0)) display_text(str(d[c]), 50, "arial", (255,255,255), screen, (resolution.x+resolution.w+30, resolution.y)) resolution.draw_button("Résolution", screen) pl_ecran.draw_button("Plein écran", screen) menu.draw_button("Menu", screen) if pl_ecran.is_clicked(bool=mouse): pygame.display.toggle_fullscreen() if resolution.is_clicked(bool=mouse): if c==2: c=0 else: c+=1 screen = pygame.display.set_mode((l,h)) if menu.is_clicked(bool=mouse): game=0 if game == 2: screen.fill((0,0,0)) joueur.refresh() joueur.draw_hitbox(screen, (255,0,0)) joueur.check_inputs() niveau.refresh() niveau.draw_hitboxes(screen) if place_meeting_tileset(joueur.x+joueur.dx, joueur.y, niveau, "X"): joueur.x -= joueur.dx if place_meeting_tileset(joueur.x, joueur.y+joueur.dy, niveau, "X"): joueur.y -= joueur.dy pygame.display.flip()
Et le fichier essentiel.py
import pygame def display_text(text,w,font,color,screen,position): screen.blit(pygame.font.SysFont(font,w).render(text,True, color), position) def place_meeting(x, y, elm): return elm.collidepoint(x,y) def place_meeting_tileset(x, y, tileset, elm): for i in tileset.hitboxes: if place_meeting(x,y,i[0]) and i[1]==elm: return True return False def sign(x): return x/abs(x) class Element: def __init__(self, position, hitbox): self.x = position[0] self.y = position[1] self.w = hitbox[0] self.h = hitbox[1] self.dx = 0 self.dy = 0 def set_position(self, x, y): self.x = x self.y = y def set_speed(self, dx, dy): self.dx = dx self.dy = dy def set_hitbox(self, w, h): self.w = w self.h = h def refresh(self): self.hitbox = pygame.Rect((self.x, self.y), (self.w, self.h)) self.x += self.dx self.y += self.dy def set_image(self, img): self.img = pygame.image.load(img) def resize_image(self, x, y): self.img = pygame.transform.scale(self.img, (x, y)) def draw_image(self, screen): screen.blit(self.img, (self.x, self.y)) def draw_hitbox(self, screen, color): pygame.draw.rect(screen, color, self.hitbox) def collide(self, elm): return self.hitbox.colliderect(elm) def colide_tileset(self, tileset, elm): for i in tileset.hitboxes: if self.collide(i[0]) and i[1]==elm: return True return False class Player(Element): def __init__(self, position, hitbox): super().__init__(position, hitbox) def check_inputs(self): keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: self.dx = -5 self.dy = 0 if keys[pygame.K_RIGHT]: self.dx = 5 self.dy = 0 if keys[pygame.K_UP]: self.dy = -5 self.dx = 0 if keys[pygame.K_DOWN]: self.dy = 5 self.dx = 0 if not keys[pygame.K_DOWN] and not keys[pygame.K_UP]: self.dy = 0 if not keys[pygame.K_LEFT] and not keys[pygame.K_RIGHT]: self.dx = 0 class Tileset: def __init__(self, level, colors, hitbox, x, y): self.level = level self.colors = colors self.w = hitbox[0] self.h = hitbox[1] self.x = x self.y = y self.hitboxes = [] def refresh(self): cursor = [self.x,self.y] for i in self.level: for j in i: if not j == " ": self.hitboxes.append([pygame.Rect(cursor[0], cursor[1], self.w, self.h), j] ) cursor[0] += self.w cursor[0] = self.x cursor[1] += self.h def set_images(self, images): self.images = images def draw_hitboxes(self, screen): cursor = [self.x, self.y] for i in self.level: for j in i: if not j == " ": pygame.draw.rect(screen, self.colors[j], (cursor[0], cursor[1], self.w, self.h)) cursor[0] += self.w cursor[0] = self.x cursor[1] += self.h class Button: def __init__(self, color,text_color, t, position): self.color = color self.w = t[0] self.h = t[1] self.x = position[0]-self.w/2 self.y = position[1]-self.h/2 self.text_color = text_color self.hitbox = pygame.Rect((self.x, self.y),(self.w, self.h)) self.overlap_color = self.color self.text_overlap_color = self.text_color self.px = 0 self.py = 0 self.state = True def draw_button(self, text, w, font, screen): self.state = False if self.overlap(): pygame.draw.rect(screen, self.overlap_color, self.hitbox) display_text(text,w,font,self.text_overlap_color,screen,(self.x + self.px, self.y + self.py)) else: pygame.draw.rect(screen, self.color, self.hitbox) display_text(text,w,font,self.text_color,screen,(self.x + self.px, self.y + self.py)) def padding(self, px, py): self.px = px self.py = py def overlap(self): return self.hitbox.collidepoint(pygame.mouse.get_pos()) def is_clicked(self, bool=True): return pygame.mouse.get_pressed()[0] and self.overlap() and bool def overlap_change(self, a,b): self.overlap_color = a self.text_overlap_color = b def set_position(self, position): self.x = position[0] self.y = position[1] class Template(Button): def __init__(self,position,w): super().__init__((37, 150, 190),(255,255,255), (w, 70), position) self.padding(12,3) self.overlap_change((255,100,100), (0,0,0)) def draw_button(self, text, screen): super().draw_button(text, 50, "arial", screen)
A voir également:
- Jeu qui ramme affreusement (PyGame)
- 94 jeu - Télécharger - Puzzle & Réflexion
- 94 degrés jeu - Télécharger - Divers Jeux
- Jeu zuma - Télécharger - Jeux vidéo
- Logo jeu - Télécharger - Jeux vidéo
- Jeu google - Guide
1 réponse
Bonsoir.
Le problème se situe dans ta méthode Tileset.refresh, à chaque appel tu ajoutes des rectangles, ce qui fait qu'on se retrouve avec des milliers de Rect très rapidement.
Donc j'imagine qu'il faut vider les hitboxes avant de mettre à jour.
def refresh(self): self.hitboxes.clear() # ...
Et peut-être vérifier avant que le x et y ont bien changé avant de tout reconstruire ?
Il faut également éviter ceci :
pygame.time.Clock().tick(fps)
Et créer un objet Clock hors boucle plutôt que le recréer à chaque tour.
Je te remercie, j'ai aussi un problème au niveau de mes collisions (voir cette discussion). En gros, les collisions de mon joueur créent un espace de 5px quand elles sont faites en bas et à droite.