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()
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()
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
Modifié le 3 mai 2023 à 12:54
Ok j'ai compris :) Merci ^^