Probleme d'affichage d'un element code python

Fermé
Zhnn - 30 avril 2023 à 22:18
 Zhnn - 3 mai 2023 à 12:54

Bonsoir a tous

j'ai déjà écris sur ce forum a propos de mon jeu. Il se trouve que j'ai un nouveau problème, qui est un peu plus urgent.
En fait j'ai voulu mettre une barre de progression dans le jeu, et elle ne s'affiche pas. C'est bizarre alors j'ai décidé de lancer cette partie du jeu "seule" et la barre s'affiche. Cependant il faut que tout soit dans le meme code et je ne comprends pas pourquoi elle ne s'affiche pas quand y a le menu, alors que tout le reste s'affiche sans problème

import pygame
import random

pygame.init()

# les dimensions de l'écran
largeur_ecran = 800
hauteur_ecran = 600

# les couleurs
BLANC = (255, 255, 255)
NOIR = (0, 0, 0)
VIOLET = (125, 20, 200)
BLEU = (0, 140, 250)


# Créer la fenêtre
ecran = pygame.display.set_mode((largeur_ecran, hauteur_ecran))
clock = pygame.time.Clock()

# titre de la fenêtre
pygame.display.set_caption("Menu du jeu")

# la police d'écriture
police = pygame.font.Font(None, 50)
FPS = 70
# Création des boutons du menu
bouton_jouer = pygame.Rect(300, 220, 250, 60)
bouton_quitter = pygame.Rect(300, 320, 250, 60)

#les formes geometriques
formes = []
for i in range(49):#nbres formes geo
    forme = {
        'x': random.randint(0, largeur_ecran),
        'y': random.randint(0, hauteur_ecran),
        'vx': random.randint(1, 5),
        'vy': random.randint(1, 5),
        'couleur': (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)),
        'taille': random.randint(30, 85),
        'forme': random.choice(['cercle', 'rectangle', 'triangle']),
    }
    formes.append(forme)

# Boucle principale du menu
menu_en_cours = True
while menu_en_cours:
    clock.tick(FPS)
    ecran.fill(NOIR)

    # Chargement de la musique de fond
    #pygame.mixer.music.load("musiquejeu.mp3")

    # Lancement de la musique de fond
    #pygame.mixer.music.play(-1)

    # Dessiner les formes géométriques
    for forme in formes:

        # Mettre à jour les positions des formes géométriques
        forme['x'] += forme['vx']
        forme['y'] += forme['vy']

        # Rebondir sur les bords de l'écran
        if forme['x'] < 0 or forme['x'] > largeur_ecran - forme['taille']:
            forme['vx'] = -forme['vx']
        if forme['y'] < 0 or forme['y'] > hauteur_ecran - forme['taille']:
            forme['vy'] = -forme['vy']

        # Dessiner la forme géométrique
        if forme['forme'] == 'cercle':
            pygame.draw.circle(ecran, forme['couleur'], (forme['x'], forme['y']), forme['taille'])
        elif forme['forme'] == 'rectangle':
            pygame.draw.rect(ecran, forme['couleur'],
                             pygame.Rect(forme['x'], forme['y'], forme['taille'], forme['taille']))
        elif forme['forme'] == 'triangle':
            pygame.draw.polygon(ecran, forme['couleur'],[(forme['x'], forme['y']), (forme['x'] + forme['taille'], forme['y']),(forme['x'] + forme['taille'] / 2, forme['y'] + forme['taille'])])

    pygame.draw.rect(ecran, VIOLET, bouton_jouer)
    pygame.draw.rect(ecran, BLEU, bouton_quitter)

    # les événements
    for evenement in pygame.event.get():
        if evenement.type == pygame.QUIT:
            menu_en_cours = False
        elif evenement.type == pygame.MOUSEBUTTONDOWN:
            if bouton_jouer.collidepoint(evenement.pos):
                print("Le joueur a cliqué sur Jouer")
            if bouton_quitter.collidepoint(evenement.pos):
                quit()

 # Accéder à la suite du jeu

            import pygame
            import random
            import time

            pygame.font.init()
            SCREEN_WIDTH = 800
            SCREEN_HEIGHT = 600
            SCREEN_COLOR = 120, 170, 255

            SOL_Y = 550

            PLAYER_COLOR = 255, 255, 255
            PLAYER_HEIGHT = 30
            PLAYER_WIDTH = 30
            EVENT_OBSTACLE_SPAWN = pygame.USEREVENT + 1
            police = pygame.font.Font(None, 50)
            FPS = 85
            FPS = 85
            DURATION = 20

            # Dimensions de la barre de progression
            BAR_WIDTH = 800
            BAR_HEIGHT = 30
            BAR_X = 0
            BAR_Y = 0
            start_time = pygame.time.get_ticks()


            class Sol(pygame.sprite.Sprite):
                def __init__(self, y):
                    super().__init__()
                    self.image = pygame.Surface((SCREEN_RECT.w, 100))
                    self.image.fill((100, 200, 80))
                    self.rect = self.image.get_rect()
                    self.rect.topleft = 0, y


            class Player(pygame.sprite.Sprite):
                def __init__(self, x, y):
                    super().__init__()
                    self.image = pygame.Surface((30, 30))
                    self.image.fill(PLAYER_COLOR)
                    self.rect = self.image.get_rect()
                    self.rect.bottomleft = x, y
                    self.x = x
                    self.y = y
                    self.jumping = False
                    self.jump_count = 20

                def move(self, amount):
                    self.rect.x += amount

                def jump(self):
                    self.jumping = True

                def collision(self, sprites): #gère les collisions
                    for sprite in sprites:
                        if isinstance(sprite, Cercle):

                            if self.rect.colliderect(sprite.rect):#vérifie si ca rentre en collision avec le rectangle du joueur
                                if self.rect.bottom <= sprite.rect.centery:
                                    self.rect.bottom = sprite.rect.top

                                elif self.rect.top >= sprite.rect.centery:
                                    #pygame.mixer.music.stop()
                                    pygame.time.wait(1000) #temps a attendre avant que ça se ferme si collision
                                    quit()

                                else:
                                    if self.rect.centerx < sprite.rect.centerx:
                                        self.rect.right = sprite.rect.left

                                    else:
                                        self.rect.left = sprite.rect.right


                        elif isinstance(sprite, Triangle):
                            if self.rect.colliderect(sprite.rect):
                                if self.rect.bottom <= sprite.rect.centery:
                                    self.rect.bottom = sprite.rect.top

                                elif self.rect.top >= sprite.rect.centery:
                                    # pygame.mixer.music.stop()
                                    pygame.time.wait(1000)
                                    quit()

                                else:
                                    if self.rect.centerx < sprite.rect.centerx:
                                        self.rect.right = sprite.rect.left

                                    else:
                                        self.rect.left = sprite.rect.right


                        elif isinstance(sprite, Rectangle):
                            if self.rect.colliderect(sprite.rect):
                                if self.rect.bottom <= sprite.rect.centery:
                                    self.rect.bottom = sprite.rect.top

                                elif self.rect.top >= sprite.rect.centery:
                                    #pygame.mixer.music.stop()
                                    pygame.time.wait(1000)
                                    quit()

                                else:
                                    if self.rect.centerx < sprite.rect.centerx:
                                        self.rect.right = sprite.rect.left

                                    else:
                                        self.rect.left = sprite.rect.right

                        elif isinstance(sprite, DoubleTriangle):
                            if self.rect.colliderect(sprite.rect):
                                if self.rect.bottom <= sprite.rect.centery:
                                    self.rect.bottom = sprite.rect.top
                                elif self.rect.top >= sprite.rect.centery:
                                    #pygame.mixer.music.stop()
                                    pygame.time.wait(1000)
                                    quit()

                                else:
                                    if self.rect.centerx < sprite.rect.centerx:
                                        self.rect.right = sprite.rect.left

                        elif isinstance(sprite, Plateforme):

                            if self.rect.colliderect(sprite.rect):
                                if self.rect.bottom <= sprite.rect.centery:
                                    self.rect.bottom = sprite.rect.top

                                elif self.rect.top >= sprite.rect.centery:
                                    #pygame.mixer.music.stop()
                                    pygame.time.wait(1000)
                                    quit()

                                else:
                                    if self.rect.centerx < sprite.rect.centerx:
                                        self.rect.right = sprite.rect.left

                                    else:
                                        self.rect.left = sprite.rect.right


                    # Retourne les sprites en collision avec le joueur
                    return tuple(s for s in sprites if s.rect.colliderect(self.rect))

                def update(self):
                    keys = pygame.key.get_pressed()
                    if keys[pygame.K_SPACE] or keys[pygame.K_UP]:
                        self.jump()

                    if self.jumping:
                        step = -(0.05 * self.jump_count ** 2) * (70 / FPS)
                        if self.jump_count > 0:
                            step *= -1
                        self.rect.y -= step
                        self.jump_count -= 1
                        if self.rect.bottom >= self.y:
                            self.rect.bottom = self.y
                            self.jumping = False
                            self.jump_count = 20
                    else:
                        if self.rect.bottom < SOL_Y:
                            self.rect.bottom += 6 #ça simule la chute de6 pixels tant que le joueur n'a pas atteint le sol

            #score
            class ScoreBoard(pygame.sprite.Sprite):
                def __init__(self, x, y):
                    super().__init__()
                    self.x = x
                    self.y = y
                    self.score = 0
                    self.font = pygame.font.SysFont('Arial', 30) #police
                    self.color = (255, 255, 255)
                    self.image = self.font.render('0', True, self.color)
                    self.rect = self.image.get_rect()
                    self.rect.topright = x, y
                    self.last_update_time = time.time()  # enregistre l'heure de la dernière mise à jour du score

                def update1(self):
                    # Vérifie si 5 secondes se sont écoulées depuis la dernière mise à jour du score
                    current_time = time.time()
                    if current_time - self.last_update_time >= 5:
                        self.add(5)  # Ajoute 5 points au score, qui augmente toutes les 5 secondes
                        self.last_update_time = current_time

                def add(self, amount): #ajoute
                    self.score += amount
                    self.image = self.font.render(str(self.score), True, self.color)
                    self.rect = self.image.get_rect()
                    self.rect.topright = self.x, self.y


            class Obstacle(pygame.sprite.Sprite): #classe pour les obstacles
                def __init__(self, x, y, width, height):
                    super().__init__()
                    self.image = pygame.Surface((width, height), pygame.SRCALPHA)
                    self.rect = self.image.get_rect()
                    self.rect.bottomleft = x, y

                def update(self):
                    self.rect.x -= 6


            class Cercle(Obstacle): #classe pour le cercle, qui est héritée d'obstacle
                def __init__(self, x, y):
                    super().__init__(x, y, 60, 60)#position du cercle sur l'écran
                    pygame.draw.circle(self.image, (0, 155, 155), (30, 30), 30) #formation du cercle


            class Triangle(Obstacle):
                def __init__(self, x, y):
                    super().__init__(x, y, 60, 60)
                    pygame.draw.polygon(self.image, (0, 255, 0), ((30, 0), (0, 60), (60, 60)))  # formation du triangle

            class Rectangle(Obstacle):
                def __init__(self, x, y):
                    super().__init__(x, y, 70, 135)
                    pygame.draw.rect(self.image, (12, 48, 255), (5, 5, 130, 130))


            class BasPlateforme(Obstacle):
                def __init__(self, x, y):
                    super().__init__(x, y, 252, 60)
                    pygame.draw.rect(self.image, (88, 35, 255), (10, 10, 670, 50))


            class DoubleTriangle(Obstacle):
                def __init__(self, x, y):
                    super().__init__(x, y, 60, 60)
                    self.image = pygame.Surface((240, 60), pygame.SRCALPHA)
                    pygame.draw.polygon(self.image, (255, 255, 0), ((30, 0), (0, 60), (60, 60)))
                    pygame.draw.polygon(self.image, (255, 255, 0), ((90, 0), (60, 60), (120, 60)))
                    self.rect = self.image.get_rect()
                    self.rect.bottomleft = x, y


            class Plateforme(Obstacle):
                def __init__(self, x, y):
                    super().__init__(x, y, 187, 187)
                    pygame.draw.rect(self.image, (185, 235, 255), (10, 10, 670, 50))


            # le spawn ; c'est une sorte de création en direct d'objets ou de personnages (ici ça va être les obstacles)
            def obstacle_spawn():
                # Choix de l'obstacle (tu choisis si tu veux plus de triangles ou de cercles)
                obstacle_class = random.choices((Cercle, Triangle, Rectangle, DoubleTriangle, Plateforme, BasPlateforme), (9, 11, 14, 15, 14, 12))[0]
                obstacle = obstacle_class(SCREEN_RECT.w, SOL_Y)
                draw_group.add(obstacle)
                obstacles_group.add(obstacle)


            def spawn_timer():
                ms = random.randrange(490, 750) #temps en millisecondes, determine le temps d'espace entre les obstacles
                pygame.time.set_timer(EVENT_OBSTACLE_SPAWN, ms)


            def sprites_clear(surface, rect):
                surface.fill(SCREEN_COLOR, rect)


            # application
            screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
            SCREEN_RECT = screen.get_rect()
            pygame.mouse.set_visible(False)
            pygame.display.set_caption("Geo")

            draw_group = pygame.sprite.RenderUpdates()
            obstacles_group = pygame.sprite.Group()

            player = Player(100, SOL_Y)
            draw_group.add(player)

            sol = Sol(SOL_Y)
            draw_group.add(sol)

            score = ScoreBoard(SCREEN_RECT.right - 10, 10) #position ou y aura le score sur l'écran
            score.update()
            draw_group.add(score)


            screen.fill(SCREEN_COLOR)
            pygame.display.update()

            clock = pygame.time.Clock()
            running = True
            points = 0
            spawn_timer()


            # boucle principale
            while running:
                clock.tick(FPS)
                score.update1()
                screen.blit(score.image, score.rect)


                for event in pygame.event.get():
                    if event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_UP or pygame.K_SPACE and not player.jumping: #touches pour sauter
                            player.jump()
                    elif event.type == EVENT_OBSTACLE_SPAWN:#generations obstacles
                        obstacle_spawn()
                        spawn_timer()
                        draw_group.remove(player)
                        draw_group.add(player)
                    elif event.type == pygame.QUIT:
                        running = False

                elapsed_time = pygame.time.get_ticks() - start_time
                progress = min(1, elapsed_time / (DURATION * 985))

                # Dessin de la barre de progression
                bar_rect = pygame.Rect(BAR_X, BAR_Y, BAR_WIDTH * progress, BAR_HEIGHT)
                pygame.draw.rect(screen, (0, 255, 0), bar_rect)


                # Vérification de la collision entre le joueur et la plateforme
                on_platform = False
                for obstacle in obstacles_group:
                    if isinstance(obstacle, Plateforme) and player.rect.colliderect(obstacle.rect):
                        if player.rect.bottom <= obstacle.rect.bottom:
                            player.rect.bottom = obstacle.rect.top
                            player.jumping = False
                            player.jump_count = 21
                            on_platform = True

                on_platform = False
                for obstacle in obstacles_group:
                    if isinstance(obstacle, BasPlateforme) and player.rect.colliderect(obstacle.rect):
                        if player.rect.bottom <= obstacle.rect.bottom:
                            player.rect.bottom = obstacle.rect.top
                            player.jumping = False
                            player.jump_count = 21
                            on_platform = True

                on_platform = False
                for obstacle in obstacles_group:
                    if isinstance(obstacle, Rectangle) and player.rect.colliderect(obstacle.rect):
                        if player.rect.bottom <= obstacle.rect.bottom:
                            player.rect.bottom = obstacle.rect.top
                            player.jumping = False
                            player.jump_count = 21
                            on_platform = True




                # Collision obstacles avec le joueur
                for sprite in player.collision(obstacles_group.sprites()):
                    obstacles_group.remove(sprite)
                    draw_group.remove(sprite)

                # Suppression des sprites hors écran
                for sprite in obstacles_group.copy().sprites():
                    if sprite.rect.right < SCREEN_RECT.x:
                        obstacles_group.remove(sprite)
                        draw_group.remove(sprite)


                draw_group.clear(screen, sprites_clear)
                draw_group.update()
                rects = draw_group.draw(screen)
                pygame.display.update(rects)

    # Afficher les boutons
    pygame.draw.rect(ecran, VIOLET, bouton_jouer)
    pygame.draw.rect(ecran, BLEU, bouton_quitter)

    # Afficher le texte des boutons
    texte_jouer = police.render("Jouer", True, BLANC)
    texte_quitter = police.render("Quitter", True, BLANC)
    ecran.blit(texte_jouer, (bouton_jouer.x + 70, bouton_jouer.y + 10))
    ecran.blit(texte_quitter, (bouton_quitter.x + 50, bouton_quitter.y + 10))

    # Rafraîchir l'écran
    pygame.display.flip()

pygame.quit()

et seul : 

import pygame
import random
import time

pygame.font.init()
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_COLOR = 120, 170, 255

SOL_Y = 550

PLAYER_COLOR = 255, 255, 255
PLAYER_HEIGHT = 30
PLAYER_WIDTH = 30
EVENT_OBSTACLE_SPAWN = pygame.USEREVENT + 1
police = pygame.font.Font(None, 50)
FPS = 85
DURATION = 20

# Dimensions de la barre de progression
BAR_WIDTH = 800
BAR_HEIGHT = 30
BAR_X = 0
BAR_Y = 0
start_time = pygame.time.get_ticks()


class Sol(pygame.sprite.Sprite):
    def __init__(self, y):
        super().__init__()
        self.image = pygame.Surface((SCREEN_RECT.w, 100))
        self.image.fill((100, 200, 80))
        self.rect = self.image.get_rect()
        self.rect.topleft = 0, y


class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((30, 30))
        self.image.fill(PLAYER_COLOR)
        self.rect = self.image.get_rect()
        self.rect.bottomleft = x, y
        self.x = x
        self.y = y
        self.jumping = False
        self.jump_count = 20

    def move(self, amount):
        self.rect.x += amount

    def jump(self):
        self.jumping = True

    def collision(self, sprites):  # gère les collisions
        for sprite in sprites:
            if isinstance(sprite, Cercle):

                if self.rect.colliderect(sprite.rect):  # vérifie si ca rentre en collision avec le rectangle du joueur
                    if self.rect.bottom <= sprite.rect.centery:
                        self.rect.bottom = sprite.rect.top

                    elif self.rect.top >= sprite.rect.centery:
                        # pygame.mixer.music.stop()
                        pygame.time.wait(1000)  # temps a attendre avant que ça se ferme si collision
                        quit()

                    else:
                        if self.rect.centerx < sprite.rect.centerx:
                            self.rect.right = sprite.rect.left

                        else:
                            self.rect.left = sprite.rect.right


            elif isinstance(sprite, Triangle):
                if self.rect.colliderect(sprite.rect):
                    if self.rect.bottom <= sprite.rect.centery:
                        self.rect.bottom = sprite.rect.top

                    elif self.rect.top >= sprite.rect.centery:
                        # pygame.mixer.music.stop()
                        pygame.time.wait(1000)
                        quit()

                    else:
                        if self.rect.centerx < sprite.rect.centerx:
                            self.rect.right = sprite.rect.left

                        else:
                            self.rect.left = sprite.rect.right


            elif isinstance(sprite, Rectangle):
                if self.rect.colliderect(sprite.rect):
                    if self.rect.bottom <= sprite.rect.centery:
                        self.rect.bottom = sprite.rect.top

                    elif self.rect.top >= sprite.rect.centery:
                        # pygame.mixer.music.stop()
                        pygame.time.wait(1000)
                        quit()

                    else:
                        if self.rect.centerx < sprite.rect.centerx:
                            self.rect.right = sprite.rect.left

                        else:
                            self.rect.left = sprite.rect.right

            elif isinstance(sprite, DoubleTriangle):
                if self.rect.colliderect(sprite.rect):
                    if self.rect.bottom <= sprite.rect.centery:
                        self.rect.bottom = sprite.rect.top
                    elif self.rect.top >= sprite.rect.centery:
                        # pygame.mixer.music.stop()
                        pygame.time.wait(1000)
                        quit()

                    else:
                        if self.rect.centerx < sprite.rect.centerx:
                            self.rect.right = sprite.rect.left

            elif isinstance(sprite, Plateforme):

                if self.rect.colliderect(sprite.rect):
                    if self.rect.bottom <= sprite.rect.centery:
                        self.rect.bottom = sprite.rect.top

                    elif self.rect.top >= sprite.rect.centery:
                        # pygame.mixer.music.stop()
                        pygame.time.wait(1000)
                        quit()

                    else:
                        if self.rect.centerx < sprite.rect.centerx:
                            self.rect.right = sprite.rect.left

                        else:
                            self.rect.left = sprite.rect.right

        # Retourne les sprites en collision avec le joueur
        return tuple(s for s in sprites if s.rect.colliderect(self.rect))

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_SPACE] or keys[pygame.K_UP]:
            self.jump()

        if self.jumping:
            step = -(0.05 * self.jump_count ** 2) * (70 / FPS)
            if self.jump_count > 0:
                step *= -1
            self.rect.y -= step
            self.jump_count -= 1
            if self.rect.bottom >= self.y:
                self.rect.bottom = self.y
                self.jumping = False
                self.jump_count = 20
        else:
            if self.rect.bottom < SOL_Y:
                self.rect.bottom += 6  # ça simule la chute de6 pixels tant que le joueur n'a pas atteint le sol


# score
class ScoreBoard(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.x = x
        self.y = y
        self.score = 0
        self.font = pygame.font.SysFont('Arial', 30)  # police
        self.color = (255, 255, 255)
        self.image = self.font.render('0', True, self.color)
        self.rect = self.image.get_rect()
        self.rect.topright = x, y
        self.last_update_time = time.time()  # enregistre l'heure de la dernière mise à jour du score

    def update1(self):
        # Vérifie si 5 secondes se sont écoulées depuis la dernière mise à jour du score
        current_time = time.time()
        if current_time - self.last_update_time >= 5:
            self.add(5)  # Ajoute 5 points au score, qui augmente toutes les 5 secondes
            self.last_update_time = current_time

    def add(self, amount):  # ajoute
        self.score += amount
        self.image = self.font.render(str(self.score), True, self.color)
        self.rect = self.image.get_rect()
        self.rect.topright = self.x, self.y


class Obstacle(pygame.sprite.Sprite):  # classe pour les obstacles
    def __init__(self, x, y, width, height):
        super().__init__()
        self.image = pygame.Surface((width, height), pygame.SRCALPHA)
        self.rect = self.image.get_rect()
        self.rect.bottomleft = x, y

    def update(self):
        self.rect.x -= 6


class Cercle(Obstacle):  # classe pour le cercle, qui est héritée d'obstacle
    def __init__(self, x, y):
        super().__init__(x, y, 60, 60)  # position du cercle sur l'écran
        pygame.draw.circle(self.image, (0, 155, 155), (30, 30), 30)  # formation du cercle


class Triangle(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 60, 60)
        pygame.draw.polygon(self.image, (0, 255, 0), ((30, 0), (0, 60), (60, 60)))  # formation du triangle


class Rectangle(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 70, 135)
        pygame.draw.rect(self.image, (12, 48, 255), (5, 5, 130, 130))


class BasPlateforme(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 252, 60)
        pygame.draw.rect(self.image, (88, 35, 255), (10, 10, 670, 50))


class DoubleTriangle(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 60, 60)
        self.image = pygame.Surface((240, 60), pygame.SRCALPHA)
        pygame.draw.polygon(self.image, (255, 255, 0), ((30, 0), (0, 60), (60, 60)))
        pygame.draw.polygon(self.image, (255, 255, 0), ((90, 0), (60, 60), (120, 60)))
        self.rect = self.image.get_rect()
        self.rect.bottomleft = x, y


class Plateforme(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 187, 187)
        pygame.draw.rect(self.image, (185, 235, 255), (10, 10, 670, 50))


# le spawn ; c'est une sorte de création en direct d'objets ou de personnages (ici ça va être les obstacles)
def obstacle_spawn():
    # Choix de l'obstacle (tu choisis si tu veux plus de triangles ou de cercles)
    obstacle_class = \
    random.choices((Cercle, Triangle, Rectangle, DoubleTriangle, Plateforme, BasPlateforme), (5, 8, 7, 8, 9, 8))[0]
    obstacle = obstacle_class(SCREEN_RECT.w, SOL_Y)
    draw_group.add(obstacle)
    obstacles_group.add(obstacle)


def spawn_timer():
    ms = random.randrange(490, 750)  # temps en millisecondes, determine le temps d'espace entre les obstacles
    pygame.time.set_timer(EVENT_OBSTACLE_SPAWN, ms)


def sprites_clear(surface, rect):
    surface.fill(SCREEN_COLOR, rect)


# application
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
SCREEN_RECT = screen.get_rect()
pygame.mouse.set_visible(False)
pygame.display.set_caption("Geo")

draw_group = pygame.sprite.RenderUpdates()
obstacles_group = pygame.sprite.Group()

player = Player(100, SOL_Y)
draw_group.add(player)

sol = Sol(SOL_Y)
draw_group.add(sol)

score = ScoreBoard(SCREEN_RECT.right - 10, 10)  # position ou y aura le score sur l'écran
score.update()
draw_group.add(score)

screen.fill(SCREEN_COLOR)
pygame.display.update()

clock = pygame.time.Clock()
running = True
points = 0
spawn_timer()

# boucle principale
while running:
    clock.tick(FPS)
    score.update1()
    screen.blit(score.image, score.rect)

    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP or pygame.K_SPACE and not player.jumping:  # touches pour sauter
                player.jump()
        elif event.type == EVENT_OBSTACLE_SPAWN:  # generations obstacles
            obstacle_spawn()
            spawn_timer()
            draw_group.remove(player)
            draw_group.add(player)
        elif event.type == pygame.QUIT:
            running = False

    elapsed_time = pygame.time.get_ticks() - start_time
    progress = min(1, elapsed_time / (DURATION * 985))


    # Dessin de la barre de progression
    bar_rect = pygame.Rect(BAR_X, BAR_Y, BAR_WIDTH * progress, BAR_HEIGHT)
    pygame.draw.rect(screen, (0, 255, 0), bar_rect)

    # Vérification de la collision entre le joueur et la plateforme
    on_platform = False
    for obstacle in obstacles_group:
        if isinstance(obstacle, Plateforme) and player.rect.colliderect(obstacle.rect):
            if player.rect.bottom <= obstacle.rect.bottom:
                player.rect.bottom = obstacle.rect.top
                player.jumping = False
                player.jump_count = 21
                on_platform = True

    on_platform = False
    for obstacle in obstacles_group:
        if isinstance(obstacle, BasPlateforme) and player.rect.colliderect(obstacle.rect):
            if player.rect.bottom <= obstacle.rect.bottom:
                player.rect.bottom = obstacle.rect.top
                player.jumping = False
                player.jump_count = 21
                on_platform = True

    on_platform = False
    for obstacle in obstacles_group:
        if isinstance(obstacle, Rectangle) and player.rect.colliderect(obstacle.rect):
            if player.rect.bottom <= obstacle.rect.bottom:
                player.rect.bottom = obstacle.rect.top
                player.jumping = False
                player.jump_count = 21
                on_platform = True

    # Collision obstacles avec le joueur
    for sprite in player.collision(obstacles_group.sprites()):
        obstacles_group.remove(sprite)
        draw_group.remove(sprite)

    # Suppression des sprites hors écran
    for sprite in obstacles_group.copy().sprites():
        if sprite.rect.right < SCREEN_RECT.x:
            obstacles_group.remove(sprite)
            draw_group.remove(sprite)

    draw_group.clear(screen, sprites_clear)
    draw_group.update()
    rects = draw_group.draw(screen)
    pygame.display.update(rects)

    pygame.display.flip()

pygame.quit()
A voir également:

2 réponses

Non, tu ne peux faire cela, ce n'est pas viable, c'est je pense d'ailleurs pour cette raison que tu as augmenté le FPS, ça rame…
Ensuite tu ne dois faire qu'un seul et unique update (ou flip) dans la boucle du jeu, c'est primordial.

Fais comme pour les autres éléments : des sprites !

Cela devrait être un réflexe, besoin d'un autre élément/objet dans le jeu, vite un Sprite ^^


Tu as un exemple de comment gérer un événement tous les x secondes avec l'apparition des obstacles.
Donc, pourquoi te servir de time.time pour le faire ? Nul besoin de ce module, pygame fournit tout ce qu'il faut.

Par exemple pour la mise à jour du score (qui doit être gérée ailleurs), tu fais un timer comme pour le spawn des obstacles, ainsi chaque fois que l'id de l'événement est présent, tu mets à jour le score.

Même chose pour la barre de progression.

Il faut aussi revoir ta façon de gérer les collisions, cela ne doit pas être fait dans la classe Player, surtout que tu en as aussi dans la boucle du jeu, je ne comprends pas ce que tu fais, ni pourquoi faire quitter le jeu brutalement lors d'une collision avec certains éléments.

Voici un exemple avec une barre de progression, avec un timer qui la fera augmenter de 0,1 % tous les 10ème de seconde. J'ai aussi modifié l'augmentation du score avec un autre timer.

Le code épuré des collisions :

import pygame
import random

pygame.font.init()
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_COLOR = 120, 170, 255

SOL_Y = 550

PLAYER_COLOR = 255, 255, 255
# PLAYER_HEIGHT = 30
# PLAYER_WIDTH = 30

FPS = 60
BAR_WIDTH = 800
BAR_HEIGHT = 30


EVENT_OBSTACLE_SPAWN = pygame.USEREVENT
EVENT_SCORE_UPDATE = pygame.USEREVENT + 1
EVENT_PROGRESS_BAR = pygame.USEREVENT + 2


class Sol(pygame.sprite.Sprite):
    def __init__(self, y):
        super().__init__()
        self.image = pygame.Surface((SCREEN_RECT.w, 100))
        self.image.fill((100, 200, 80))
        self.rect = self.image.get_rect()
        self.rect.topleft = 0, y


class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((30, 30))
        self.image.fill(PLAYER_COLOR)
        self.rect = self.image.get_rect()
        self.rect.bottomleft = x, y
        self.x = x
        self.y = y
        self.jumping = False
        self.jump_count = 20

    def jump(self):
        self.jumping = True

    def collision(self, sprites):
        return tuple(s for s in sprites if s.rect.colliderect(self.rect))

    def update(self):
        if self.jumping:
            step = -(0.05 * self.jump_count ** 2) * (30 / FPS)
            if self.jump_count > 0:
                step *= -2
            self.rect.y -= step
            self.jump_count -= 1
            if self.rect.bottom >= self.y:
                self.rect.bottom = self.y
                self.jumping = False
                self.falling = True
                self.jump_count = 20


# score
class ScoreBoard(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.x = x
        self.y = y
        self.score = 0
        self.font = pygame.font.SysFont('Arial', 30)  # police
        self.color = (255, 255, 255)
        self.image = self.font.render('0', True, self.color)
        self.rect = self.image.get_rect()
        self.rect.topright = x, y

    def add(self, amount):  # ajoute
        self.score += amount
        self.image = self.font.render(str(self.score), True, self.color)
        self.rect = self.image.get_rect()
        self.rect.topright = self.x, self.y


class Obstacle(pygame.sprite.Sprite):  # classe pour les obstacles
    def __init__(self, x, y, width, height):
        super().__init__()
        self.image = pygame.Surface((width, height), pygame.SRCALPHA)
        self.rect = self.image.get_rect()
        self.rect.bottomleft = x, y

    def update(self):
        self.rect.x -= 6


class Cercle(Obstacle):  # classe pour le cercle, qui est héritée d'obstacle
    def __init__(self, x, y):
        super().__init__(x, y, 60, 60)  # position du cercle sur l'écran
        pygame.draw.circle(
            self.image, (0, 155, 155), (30, 30), 30
        )  # formation du cercle


class Triangle(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 60, 60)
        pygame.draw.polygon(
            self.image, (0, 255, 0), ((30, 0), (0, 60), (60, 60))
        )  # formation du triangle


class Rectangle(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 70, 135)
        pygame.draw.rect(self.image, (12, 48, 255), (5, 5, 130, 130))


class BasPlateforme(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 252, 60)
        pygame.draw.rect(self.image, (88, 35, 255), (10, 10, 670, 50))


class DoubleTriangle(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 60, 60)
        self.image = pygame.Surface((240, 60), pygame.SRCALPHA)
        pygame.draw.polygon(self.image, (255, 255, 0), ((30, 0), (0, 60), (60, 60)))
        pygame.draw.polygon(self.image, (255, 255, 0), ((90, 0), (60, 60), (120, 60)))
        self.rect = self.image.get_rect()
        self.rect.bottomleft = x, y


class Plateforme(Obstacle):
    def __init__(self, x, y):
        super().__init__(x, y, 187, 187)
        pygame.draw.rect(self.image, (185, 235, 255), (10, 10, 670, 50))


class ProgressBar(pygame.sprite.Sprite):
    def __init__(self, width, height, color):
        super().__init__()
        self.image = pygame.Surface((width, height), pygame.SRCALPHA).convert_alpha()
        self.rect = self.image.get_rect()
        self.color = color
        self._percent = 0

    def is_full(self):
        return self._percent == 100

    def increase(self, percent):
        if self._percent == 100:
            return
        self._percent += percent
        self._percent = min(100, self._percent)
        width = self.rect.w / 100 * self._percent
        pygame.draw.rect(self.image, self.color, (0, 0, width, self.rect.h))


# le spawn ; c'est une sorte de création en direct d'objets ou de personnages (ici ça va être les obstacles)
def obstacle_spawn():
    # Choix de l'obstacle (tu choisis si tu veux plus de triangles ou de cercles)
    obstacle_class = random.choices(
        (Cercle, Triangle, Rectangle, DoubleTriangle, Plateforme, BasPlateforme),
        (5, 8, 7, 8, 9, 8),
    )[0]
    obstacle = obstacle_class(SCREEN_RECT.w, SOL_Y)
    draw_group.add(obstacle)
    obstacles_group.add(obstacle)


def spawn_timer(ms=-1):
    if ms == -1:
        ms = random.randrange(490, 750)
    pygame.time.set_timer(EVENT_OBSTACLE_SPAWN, ms)


def sprites_clear(surface, rect):
    surface.fill(SCREEN_COLOR, rect)


# application
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
SCREEN_RECT = screen.get_rect()
pygame.mouse.set_visible(False)
pygame.display.set_caption("Geo")

draw_group = pygame.sprite.RenderUpdates()
obstacles_group = pygame.sprite.Group()

player = Player(100, SOL_Y)
sol = Sol(SOL_Y)
score = ScoreBoard(SCREEN_RECT.right - 10, 10)
progress_bar = ProgressBar(BAR_WIDTH, BAR_HEIGHT, (255, 165, 0, 128))
progress_bar.rect.topleft = 0, 0

draw_group.add(player, sol, score, progress_bar)

screen.fill(SCREEN_COLOR)
pygame.display.update()

clock = pygame.time.Clock()
running = True
spawn_timer()
pygame.time.set_timer(EVENT_SCORE_UPDATE, 5000)
pygame.time.set_timer(EVENT_PROGRESS_BAR, 100)

# boucle principale
while running:
    clock.tick(FPS)
    pygame.display.set_caption(f"Geo - {round(clock.get_fps())} FPS")
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP or pygame.K_SPACE and not player.jumping:
                player.jump()
        elif event.type == EVENT_OBSTACLE_SPAWN:  # generations obstacles
            obstacle_spawn()
            spawn_timer()
            draw_group.remove(player)
            draw_group.add(player)
        elif event.type == EVENT_SCORE_UPDATE:
            score.add(5)
        elif event.type == EVENT_PROGRESS_BAR:
            progress_bar.increase(0.1)
            if progress_bar.is_full():
                print('progression réussie !')
                # Annulation du timer (mise à 0 des ms)
                pygame.time.set_timer(EVENT_PROGRESS_BAR, 0)
                # Faire ce qu'il y a à faire.
                # Par exemple, arrêt des autres animations
                spawn_timer(0)
                pygame.time.set_timer(EVENT_SCORE_UPDATE, 0)
        elif event.type == pygame.QUIT:
            running = False

    # Collision obstacles avec le joueur
    for sprite in player.collision(obstacles_group.sprites()):
        obstacles_group.remove(sprite)
        draw_group.remove(sprite)

    # Suppression des sprites hors écran
    for sprite in obstacles_group.copy().sprites():
        if sprite.rect.right < SCREEN_RECT.x:
            obstacles_group.remove(sprite)
            draw_group.remove(sprite)

    draw_group.clear(screen, sprites_clear)
    draw_group.update()
    rects = draw_group.draw(screen)
    pygame.display.update(rects)

pygame.quit()
1

Ok j'ai compris :) Merci ^^

0

Bonsoir.

Tu ne peux pas copier/coller comme ça un script entier dans la boucle du jeu, ou alors c'est une erreur ?

0

Oui ça me paraissait bizarre au tout début mais en fait si si ça fonctionne et je travaillais a partir du code complet. C'est juste cette barre qui rencontre un problème

0