Jeu Space Invaders avec Pygame – Partie 4

Dans la partie précèdente, nous avons construit la base de notre vue Jeu avec Pygame.
Aujourd’hui nous terminerons ce tutoriel en créant la boucle de jeu.

pygame tutoriel

Le tutoriel est décomposé ainsi :

  • Création de la boucle de jeu
  • Traitement des évènements utilisateurs
  • Gestion du mouvement et collisions

Création de la boucle de jeu

Commençons par ajouter le code suivant pour définir une boucle infinie pour notre jeu.

def run(self):
    mainloop = True
    while mainloop:
        self.clock.tick(50)
        self.screen.fill([0, 0, 0])
        self.screen.blit(self.bg, self.bg_rect)

Traitements des évènements utilisateurs

Evènements souris

Quand l’utilisateur clique sur la croix de l’application, nous souhaitons fermer le jeu.

# run
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        sys.exit()

Evènements clavier

A présent, définissons les actions à effectuer quand l’utilisateur appuie sur les touches du clavier.

# run

keys = pygame.key.get_pressed()

if keys[pygame.K_LEFT]:
    self.spaceship.sprite.x -= 10
    if self.spaceship.shooting is False:
        self.bullet.sprite.x -= 10
elif keys[pygame.K_RIGHT]:
    self.spaceship.sprite.x += 10
    if self.spaceship.shooting is False:
        self.bullet.sprite.x += 10
elif keys[pygame.K_SPACE]:
    self.spaceship.shoot = True
elif keys[pygame.K_ESCAPE]:
    # Go back to the game menu
    mainloop = False
    self.escape_selected = True
    pygame.mixer.music.rewind()

Gestion du mouvements et collisions

Course du projectile

Quand la variable shoot est activé, on souhaite déplace verticalement le projectile et lancer un effet sonore.

if self.spaceship.shoot is True:
    self.laser_sound.play()

    if self.bullet.sprite.y > 0 and self.invader_exploding is False:
        self.spaceship.shooting = True
        self.bullet.sprite = self.bullet.sprite.move([0, -6])
    else:
        self.laser_sound.fadeout(1000)
        self.bullet.sprite.x, self.bullet.sprite.y = (
	    self.spaceship.sprite.x + self.spaceship.sprite.width / 2,
            self.spaceship.sprite.y
        )
        self.spaceship.shoot = False
        self.spaceship.shooting = False
        self.invader_exploding = False

Mouvement des invaders et Collision

item_to_remove = None
# Invader Collision + Vertical Movement

# Allow slowly vertical movement
if self.timecount_m > self.nasty_move_time:
    self.invaders_moving = True
else:
    self.invaders_moving = False
    self.timecount_m += self.clock.get_time()

if len(self.invaders) > 0:
    for i, invader in enumerate(self.invaders):
        if invader.sprite.collidepoint(
            self.bullet.sprite.x, self.bullet.sprite.y
        ):
            item_to_remove = i
            self.invader_exploding = True
        else:
            if self.invaders_moving and not self.game_over:
                invader.sprite.y += 15
                self.timecount_m = 0
            self.screen.blit(invader.image, invader.sprite)

# Remove dead invader:
if item_to_remove is not None:
    del self.invaders[item_to_remove]

Sélection aléatoire d’un invader et armement du projectile

if not self.has_already_chosen:
    # Select random invader among survivor invaders

    if len(self.invaders) > 0 and not self.game_over:
        if len(self.invaders) is not 1:
            self.randinvader = self.invaders[randint(1, len(self.invaders) - 1)]
        else:
            self.randinvader = self.invaders[0]
        self.has_already_chosen = True
        posx = self.randinvader.sprite.x
        posy = self.randinvader.sprite.y
        width = self.randinvader.sprite.width
        height = self.randinvader.sprite.height
        self.ennemybullet = Bullet((posx + width / 2, posy + height))
    else:
        self.victory = True

Course du projectile de l’invader sélectionné

self.timecount += self.clock.get_time()

# Handle the bullet shot by the random invader

if self.timecount > self.nasty_shoot_time and self.has_already_chosen:
    self.timecount = 0
    self.has_already_chosen = False

elif self.timecount < self.nasty_shoot_time and self.has_already_chosen:
    if self.ennemybullet.sprite.y < self.scr_height:
        self.ennemybullet.sprite = self.ennemybullet.sprite.move([0, 6])
        self.screen.blit(self.ennemybullet.image, self.ennemybullet.sprite)

Affichage du vaisseau et gestion des collisions

# Shuttle Displaying and Colision
if self.spaceship.sprite.collidepoint(
    self.ennemybullet.sprite.x, self.ennemybullet.sprite.y
) and self.spaceship.exploding is False:
    self.timecount = self.nasty_shoot_time
    self.has_already_chosen = False
    self.spaceship.exploding = True
else:
    self.screen.blit(self.bullet.image, self.bullet.sprite)
    self.screen.blit(self.spaceship.image, self.spaceship.sprite)

Gestion des vies restantes et affichage

if self.spaceship.exploding:
    self.spaceship.exploding = False
    if len(self.lifes) > 0:
        self.lifes.pop()
    else:
        self.game_over = True
        self.spaceship.exploding = False

# Remaining lifes
pygame.draw.rect(
    self.screen, (255, 255, 255),
    [self.scr_width - 120, 0, 120, 40], 1
)

for life in self.lifes:
    self.screen.blit(life.image, life.sprite)

Construction des messages gameover ou victory

if self.victory:
    self.screen.blit(
        self.label_victory,
        (
            self.scr_width / 2 - self.label_victory.get_rect().width / 2,
            self.scr_height / 2 - self.label_victory.get_rect().height / 2
        )
    )

if self.game_over:
    self.screen.blit(
        self.label_game_over,
        (
	    self.scr_width / 2 - self.label_game_over.get_rect().width / 2,
	    self.scr_height / 2 - self.label_game_over.get_rect().height / 2
        )
    )

Affichage de l’écran

pygame.display.flip()

# 4 seconds break if game_over or victory
if self.game_over or self.victory:
    pygame.time.delay(4000)
    mainloop = False

Félicitations, le tutoriel se termine, vous savez à présent créer un jeu vidéo 2d avec Python.

0

Laisser un commentaire