[Pygame] Problème pour afficher un groupe de sprites

Fermé
ipex300 - Modifié le 29 sept. 2022 à 15:12
 gaffeur - 29 sept. 2022 à 20:26

Bonjour,

Je débute en python j'aimerais pouvoir faire mes propres jeux avec pygame. 

Dans mon programme, quand j'essaye de d'afficher mon groupe de sprites, ça ne marche pas et je ne sais pas pourquoi.

Voici mon code :

import pygame

pygame.init()
background = pygame.image.load("PygameAssets-main/bg.jpg")
ecran = pygame.display.set_mode((1080, 720))
joueur = pygame.image.load("PygameAssets-main/player.png")
x = 400
y = 450
ecran.blit(joueur, (x, y))
velocity = 5
pygame.key.set_repeat(4,20)

class projectile(pygame.sprite.Sprite):
     def __init__(self):
         super().__init__()
         self.image = pygame.image.load("PygameAssets-main/projectile.png")
         self.rect = self.image.get_rect()

running = True
v = 0
while running == True:
    projectilegroup = pygame.sprite.Group()

    def launch():
        global v
        v += 1
        print(v)
        projectilegroup.add(projectile())

    ecran.blit(background, (0, -250))
    projectilegroup.draw(ecran)
    ecran.blit(joueur, (x,y))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT and x < 915:
                x += velocity
            elif event.key == pygame.K_LEFT and x > -30:
                x -= velocity
            elif event.key == pygame.K_SPACE:
                print(event.key)
                launch()
    pygame.display.update()
pygame.quit()

Merci de me répondre.

1 réponse

Bonsoir, le problème est que tu déclares à chaque tour de boucle ton groupe de sprite, il en va de même pour ta fonction launch, elle ne doit pas être dans ta boucle.

Ce qui doit se passer grosso-modo dans ton code, le joueur tire, un nouveau projectile est créé, sa position doit ensuite se déplacer automatiquement dans une direction donnée, il devra être détruit au cas où il rencontrera un éventuel obstacle ou s'il sort de l'écran.

Ce déplacement, tu peux le faire dans ta classe Projectile en modifiant la coordonnée du rectangle, et un avantage d'utiliser les groups est entre autre de pouvoir faire un update du group, ce qui fera automatiquement un update de chaque sprite du group, on peut en tirer avantage ici en se servant de la méthode update pour faire bouger les projectiles.

Préfère utiliser pygame.key.get_pressed() plutôt que pygame.key.set_repeat(), cela aura l'avantage de pouvoir utiliser plusieurs touches clavier simultanément.

Il est aussi judicieux de réguler le fps du jeu en se servant de pygame.time.Clock()

J'ai préféré que la classe projectile gère elle même ses groupes.

Voici un peu ce que ça donnerait suivant ces indications, n'ayant pas les images, j'ai modifié légèrement afin de faire un simple exemple reproductible, à toi de remettre le code de tes images.

import pygame

FPS = 60
PLAYER_VELOCITY = 3
FIRE_DELAY = 150  # délai d'attente entre chaque tir en ms
SCREEN_WIDTH = 1080
SCREEN_HEIGHT = 720
pygame.init()

ecran = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

# background= pygame.image.load("PygameAssets-main/bg.jpg")
background = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT)).convert_alpha()
background.fill(pygame.Color('black'))
# joueur = pygame.image.load("PygameAssets-main/player.png")
joueur = pygame.Surface((50, 20)).convert_alpha()
joueur.fill(pygame.Color('blue'))

projectile_group = pygame.sprite.Group()

x = 400
y = 450


class projectile(pygame.sprite.Sprite):
    speed = 12

    def __init__(self, x, y, group):
        super().__init__()
        group.add(self)
        self.group = group
        # self.image = pygame.image.load("PygameAssets-main/projectile.png")
        self.image = pygame.Surface((25, 5)).convert_alpha()
        self.image.fill(pygame.Color('yellow'))
        self.rect = self.image.get_rect()
        self.rect.topleft = x, y

    def update(self):
        self.rect.x += self.speed
        if self.rect.x > SCREEN_WIDTH:
            self.group.remove(self)


clock = pygame.time.Clock()
running = True
fire_last_time = 0
while running:
    ecran.blit(background, (0, -250))
    # déplacements des projectiles
    projectile_group.update()
    projectile_group.draw(ecran)
    ecran.blit(joueur, (x, y))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    keys = pygame.key.get_pressed()
    if keys[pygame.K_RIGHT] and x < SCREEN_WIDTH - joueur.get_width():
        x += PLAYER_VELOCITY
    if keys[pygame.K_LEFT] and x > 0:
        x -= PLAYER_VELOCITY
    if keys[pygame.K_SPACE] and fire_last_time + FIRE_DELAY < pygame.time.get_ticks():
        projectile(x + joueur.get_width(), y, projectile_group)
        fire_last_time = pygame.time.get_ticks()
    pygame.display.update()
    clock.tick(FPS)
pygame.quit()

Il y a évidemment plein de choses à modifier, la position verticale du projectile, la direction, si le joueur va vers la gauche, le projectile sera donc tiré vers cette même direction.

0