Collisions qui laissent un espace PyGame
vertigo -
Bonjour,
Les collisions de mon joueur laissent un espace de 5 pixels lorsqu'elles sont effectuées en bas et à droite. Voila mon code. Il y a deux fichiers)
main.py
import pygame from essentiels import * #Initialisation élémentaire pygame.init() x,y=0,0 c=1 d=[(1920, 1080), (1280, 720), (1360, 768)] l,h=d[c] screen = pygame.display.set_mode((l,h)) game=0 menu_=0 mouse = True fps=60 #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), (30,30)) 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() joueur.back_tileset(niveau, "X") niveau.refresh() niveau.draw_hitboxes(screen) pygame.display.flip()
elements.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 def back_tileset(self, tileset, elm): if self.dx<0: if place_meeting_tileset(self.x+self.dx, self.y, tileset, elm): self.dx=0 if place_meeting_tileset(self.x+self.dx, self.y+self.h, tileset, elm): self.dx=0 else: if place_meeting_tileset(self.x+self.dx+self.w, self.y, tileset, elm): self.dx=0 if place_meeting_tileset(self.x+self.dx+self.w, self.y+self.h, tileset, elm): self.dx=0 if self.dy<0: if place_meeting_tileset(self.x, self.y+self.dy, tileset, elm): self.dy=0 if place_meeting_tileset(self.x+self.w, self.y+self.dy, tileset, elm): self.dy=0 else: if place_meeting_tileset(self.x, self.y+self.dy+self.h, tileset, elm): self.dy=0 if place_meeting_tileset(self.x+self.w, self.y+self.dy+self.h, tileset, elm): self.dy=0 def back(self,elm): if self.dx<0: if place_meeting(self.x+self.dx, self.y, elm): self.dx=0 if place_meeting(self.x+self.dx, self.y+self.h, elm): self.dx=0 else: if place_meeting(self.x+self.dx+self.w, self.y, elm): self.dx=0 if place_meeting(self.x+self.dx+self.w, self.y+self.h, elm): self.dx=0 if self.dy<0: if place_meeting(self.x, self.y+self.dy, elm): self.dy=0 if place_meeting(self.x+self.w, self.y+self.dy, elm): self.dy=0 else: if place_meeting(self.x, self.y+self.dy+self.h, elm): self.dy=0 if place_meeting(self.x+self.w, self.y+self.dy+self.h, elm): self.dy=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): self.hitboxes.clear() 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)
- Xxxxxxxxxxxxx
- Espace insécable - Guide
- Espace de stockage gmail plein - Guide
- Espace stockage google - Guide
- Chaque paragraphe doit être espacé de 0,42 cm ou 12 pt du paragraphe qui suit - Guide
- Liberer espace ipad - Guide
1 réponse
Salut.
Difficile de s'y retrouver dans ton code.
Puis ce n'est pas au joueur de gérer ce qu'il va se passer en cas de collision, ni même gérer ses propres déplacements, mais à un niveau supérieur, là où les éléments ont été déclarés.
Généralement, et bien plus facile à gérer, est de garder en mémoire la position précédente des éléments pouvant se mouvoir, et lorsqu'une collision est détectée, le gestionnaire des collisions replace les éléments via une méthode des éléments genre move_back.
Pygame a plusieurs méthodes pour détecter des collisions de rectangles, on n'utilise généralement pas Rect.collidepoint, mais plus Rect.colliderect, Rect.collidelist, inutile de se prendre le chou à tester chaque points extérieurs de tes rectangles.