Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème de positionnement des rect sur pygames

Rect mal placé par rapport aux entités

    26 mars 2019 à 21:02:45

    Je suis en classe de terminale S et nous devons, en groupe, rendre un projet de fin d'année pour le bac sur python.

    Notre projet est un mini jeu 2D mais nous rencontrons un problème qui est que les "rect" sont mal placés par rapports à toutes les entités ce qui nous empêche faire des collisions normales. J'ai passé du temps à chercher le problème sur internet et dans mon code mais je ne trouve rien. L'erreur doit être bête et sous mes yeux mais je n'arrive pas à mettre la main dessus ! Mon code se trouve ci-dessous, je sais que ceux qui le liront le trouveront probablement horrible, mal optimisé, il l'est mais je ne suis pas un programmeur expérimenté puisque je n'ai que 2h de python par semaines depuis le début de l'année scolaire. J'adore programmer donc si une âme charitable passe par là lit mon code et veux bien m'aider je suis ouvert à toute corrections des défauts de mon programme (sauf les plus minimes car je n'est pas énormément de temps).

    Merci d'avance.🙇‍♂️  :D

    PS: Je précise que le jeu n'est pas du tout terminé il n'y a pour le moment pas grands choses !

    import os
    import pygame
    import pygame.mixer
    from pygame.locals import*
    #fonction créant un dictionnaire pour entités
    def entite(rectan):
        entite={'rect':rectan,'v':(0,0),"position":rectan.topleft}
        return entite
    
    #fonction permettant de changer la vitesse d'une entite
    def chger_v(entite, acceleration):
        vx, vy= entite["v"]
        ax, ay= acceleration
        entite["v"]=(vx+ax,vy+ay)
    
    #fonction permettant de changer la position d'une entite
    def chger_posi(entite):
        vx, vy=entite["v"]
        x, y=entite["position"]
        x+=vx*temp_ecoule/1000
        y+=vy*temp_ecoule/1000
        entite["position"]=(x,y)
        entite["rect"].midbottom=entite["position"]
    
    #fonction permettant à une entite de ne pas traverser les bords de la zone de jeu
    def limite(entite):
        x,y = entite["position"]
        largeur, hauteur= entite["rect"].size
        if x<20 and y>220-hauteur and y<276-hauteur:
            x=745
        elif x<50 and y<220-hauteur or x<50 and y>276-hauteur:
            x=50
        elif x>755 and y>220-hauteur and y<276-hauteur:
            x=55
        elif x>750-largeur and y<220-hauteur or x>750-largeur and y>276-hauteur:
            x=750-largeur
        if y<15 and x>368-25 and x<428-25:
            y=445-hauteur
        elif y<20 and x<368-25 or y<20 and x>428-25:
            y=20
        elif y>470-hauteur and x>368-25 and x<428-25:
            y=25
        elif y>450-hauteur and x<368-25 or y>450-hauteur and x>428-25:
            y=450-hauteur
        entite["position"]=(x,y)
        entite["rect"].midbottom=entite["position"]
    
    pygame.init()
    
    #creation de la fenêtre
    taille_fenetre=(1000,500)
    screen=pygame.display.set_mode(taille_fenetre)
    
    #réglage de quelques couleurs
    bleu_ciel=(185,240,240)
    rouge=(255,0,0)
    jaune=(255,245,43)
    vert=(50,255,0)
    bleu=(0,20,255)
    noir=(0,0,0)
    blanc=(255,255,255)
    marron=(88,41,0)
    magenta=(227,22,233)
    
    #import de tout ce qui est nécessaire
    son=pygame.mixer.music.load("assets/musique/music.mp3")
    elektraG=pygame.image.load("assets/Elektra/ElektraG.png").convert_alpha()
    elektraH=pygame.image.load("assets/Elektra/ElektraH.png").convert_alpha()
    elektraB=pygame.image.load("assets/Elektra/ElektraB.png").convert_alpha()
    elektraD=pygame.image.load("assets/Elektra/Elektra.png").convert_alpha()
    tir_image=pygame.image.load("assets/tir/laser.png").convert()
    tir_image_v=pygame.image.load("assets/tir/laser_v.png").convert()
    none=pygame.image.load("assets/tir/none.png").convert_alpha()
    solbois=pygame.image.load("assets/Sol/bois.png").convert()
    murpierre=pygame.image.load("assets/Mur/pierre.png").convert_alpha()
    fantome_img=pygame.image.load("assets/monstres/fantome.png").convert_alpha()
    vie_surface=pygame.image.load("assets/interface/heart.png").convert()
    vie_surface.set_colorkey(magenta)
    
    #creation des entites par rapport à l'image
    elektra_surface=elektraD
    elektra=entite(elektra_surface.get_rect(center=(400,250)))
    
    fantome_surface=fantome_img
    fantome=entite(fantome_surface.get_rect(center=(100,250)))
    
    temps=pygame.time.Clock()
    
    #quelques variables
    vitesseElektra=500
    vitesseTir=200
    continuer=True
    tir_d=False; tir_g=False; tir_h=False; tir_b=False
    vie=3
    
    pygame.mixer.music.play(loops=-1, start=0.0)
    
    #boucle de jeu principale
    while continuer:
        screen.fill(marron)
        screen.blit(solbois,(50,50))
        screen.blit(murpierre,(0,0))
    
        #détection des evennements pour faire fonctionner le jeu
        for event in pygame.event.get():
            if event.type==QUIT:
                continuer=False
            elif event.type==KEYDOWN:
                if event.key==K_d:
                    chger_v(elektra,(vitesseElektra,0))
                elif event.key==K_a:
                    chger_v(elektra,(-vitesseElektra,0))
                if event.key==K_w:
                    chger_v(elektra,(0,-vitesseElektra))
                elif event.key==K_s:
                    chger_v(elektra,(0,vitesseElektra))
                if event.key==K_RIGHT:
                    if tir_d==False and tir_g==False and tir_h==False and tir_b==False:
                        elektra_surface=elektraD
                        tir_surface=tir_image
                        x,y=elektra["position"]
                        tir=entite(tir_surface.get_rect(center=(x+25,y+46)))
                        tir_d=True
                        pygame.time.set_timer(USEREVENT,500)
                        chger_v(tir,(vitesseTir,0))
                if event.key==K_LEFT:
                    if tir_d==False and tir_g==False and tir_h==False and tir_b==False:
                        elektra_surface=elektraG
                        tir_surface=tir_image
                        x,y=elektra["position"]
                        tir=entite(tir_surface.get_rect(center=(x+25,y+46)))
                        tir_g=True
                        pygame.time.set_timer(USEREVENT,500)
                        chger_v(tir,(-vitesseTir,0))
                if event.key==K_UP:
                    if tir_d==False and tir_g==False and tir_h==False and tir_b==False:
                        elektra_surface=elektraH
                        tir_surface=tir_image_v
                        x,y=elektra["position"]
                        tir=entite(tir_surface.get_rect(midleft=(x+25,y+46)))
                        tir_h=True
                        pygame.time.set_timer(USEREVENT,500)
                        chger_v(tir,(0,-vitesseTir))
                if event.key==K_DOWN:
                    if tir_d==False and tir_g==False and tir_h==False and tir_b==False:
                        elektra_surface=elektraB
                        tir_surface=tir_image_v
                        x,y=elektra["position"]
                        tir=entite(tir_surface.get_rect(midleft=(x+15,y+54)))
                        tir_b=True
                        pygame.time.set_timer(USEREVENT,500)
                        chger_v(tir,(0,vitesseTir))
    
            elif event.type==KEYUP:
                if event.key==K_d:
                    chger_v(elektra,(-vitesseElektra,0))
                elif event.key==K_a:
                    chger_v(elektra,(vitesseElektra,0))
                if event.key==K_w:
                    chger_v(elektra,(0,vitesseElektra))
                elif event.key==K_s:
                    chger_v(elektra,(0,-vitesseElektra))
    
            if event.type==USEREVENT:
                if tir_d==True:
                    tir_d=False
                    chger_v(tir,(-vitesseTir,0))
                elif tir_g==True:
                    tir_g=False
                    chger_v(tir,(vitesseTir,0))
                elif tir_h==True:
                    tir_h=False
                    chger_v(tir,(vitesseTir,0))
                elif tir_b==True:
                    tir_b=False
                    chger_v(tir,(-vitesseTir,0))
    
        #premier monstre temporaire
        xm, ym=fantome["position"]
        if xm>600:
            chger_v(fantome,(-4,0))
        elif xm<100:
            chger_v(fantome,(4,0))
    
        #logique du jeu
        #collision
        if elektra["rect"].colliderect(fantome["rect"]):
            print("degats")
    
        if tir_d==True or tir_g==True or tir_h==True or tir_b==True:
            if tir["rect"].colliderect(fantome["rect"]):
                print("touché")
                if tir_d==True:
                    tir_d=False
                    chger_v(tir,(-vitesseTir,0))
                elif tir_g==True:
                    tir_g=False
                    chger_v(tir,(vitesseTir,0))
                elif tir_h==True:
                    tir_h=False
                    chger_v(tir,(vitesseTir,0))
                elif tir_b==True:
                    tir_b=False
                    chger_v(tir,(-vitesseTir,0))
    
        temp_ecoule=temps.tick()
        limite(elektra)
        chger_posi(elektra)
        chger_posi(fantome)
    
        #remplissage des rect avec une couleur me permettants de voir la position de ceux-ci
        pygame.draw.rect(screen,rouge,elektra["rect"])
        pygame.draw.rect(screen,bleu,fantome["rect"])
    
        #affichage
        if tir_d or tir_g or tir_h:
            chger_posi(tir)
            screen.blit(tir_surface,tir["position"])
            pygame.draw.rect(screen,vert,tir["rect"])
        screen.blit(elektra_surface,elektra["position"])
        if tir_b:
            chger_posi(tir)
            screen.blit(tir_surface,tir["position"])
            pygame.draw.rect(screen,vert,tir["rect"])
        screen.blit(fantome_surface,fantome["position"])
    
        #futur système de vie
        if vie>=1:
            screen.blit(vie_surface,(820,50))
            if vie>=2:
                screen.blit(vie_surface,(870,50))
                if vie>=3:
                    screen.blit(vie_surface,(920,50))
                    if vie>=4:
                        screen.blit(vie_surface,(820,80))
                        if vie>=5:
                            screen.blit(vie_surface,(870,80))
                            if vie>=6:
                                screen.blit(vie_surface,(920,80))
        pygame.display.flip()
    
    pygame.quit()



    Voici une image du jeu montrant les rect mal placés du joueur, du monstre et du tir respectivement en rouge, bleu et vert

    Voici une image du jeu avec les rect mal placés du joueur, du monstre et du tir respectivement en rouge, bleu et vert.

    -
    Edité par maximechalumeau 26 mars 2019 à 21:05:06

    • Partager sur Facebook
    • Partager sur Twitter
      28 mars 2019 à 18:18:20

      Plein de choses à dire:

      - donne de meilleurs nom à tes fonctions par exemple accelerer, deplacer set_pos, set_acceleration ... plutôt que chg_posi ...

      - en python c'est inutile de mettre if truc == True: on écrit juste if truc:

      - le "futur système de vie" n'est pas du tout mathématique il plus élégant et pratique d'utiliser les modulos

      - ton code est moche et compliqué parce que tu utilise un dictionnaire pour définir tes 'entité' alors que les classes sont faites pour ça

      - tu as écrit plein de chiffres et de conditions dans ta fonction limite, je suis presque sûr que tu peux faire trouver ces informations en prenant comme paramètre la fenetre et en utilise screen.get_rect()

      Une fois ton code devenu un peu plus clair reposte le et déjà ce sera plus facile de t'aider

      -
      Edité par Coliculus 28 mars 2019 à 18:37:51

      • Partager sur Facebook
      • Partager sur Twitter

      Problème de positionnement des rect sur pygames

      × 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