Jeu Space Invaders avec Pygame – Partie 2

Dans la première partie, nous avons posé les bases pour réaliser un space invaders like avec Pygame. Cliquez pour voir la première partie du tutoriel.

Aujourd’hui, nous allons créer la vue Menu.

pygame-tutoriel-space-invaders

Initialisation de Pygame

Tout d’abord, initialisons Pygame pour nous aider à créer l’écran Menu.

#!/usr/bin/python3
import sys
import pygame
pygame.init()

Création du Menu

Cette partie se décompose en sous objectif.

  • Initialisation du Menu
  • Positionnement des éléments visuels
  • Interaction avec l’utilisateur

Initialisation du Menu

Premièrement, nous définissons la classe pour gérer le menu avec les paramètres suivants.

  • screen : contient la hauteur et la largeur de l’écran
  • bg_color : arrière plan en noir par défaut
  • font : Police de caractère par défaut
  • font_size : Taille de la police de caractère
  • font_color : Couleur de la police en blanc
class GameMenu:

	def __init__(
            self, screen, items,
            bg_color=(0, 0, 0), font=None,
            font_size=100, font_color=(255, 255, 255)):

A présent, nous paramétrons la hauteur et largeur de l’écran à partir de la variable screen.

# init
self.screen = screen
self.scr_width = self.screen.get_rect().width
self.scr_height = self.screen.get_rect().height

Ensuite, ajoutons un fond d’écran et des effets sonores pour mettre dans l’ambiance.

# Background Main Menu
self.bg_color = bg_color
self.bg_img = pygame.image.load('resources/images/menubackground.jpg')
self.bg_img_rect = self.bg_img.get_rect()

# Sound Menu Change
self.menu_sound = pygame.mixer.Sound('resources/sounds/menu_noise.wav')
self.valid_menu_sound = pygame.mixer.Sound('resources/sounds/menu_valid_sound.wav')

# Menu Music
self.menu_music = pygame.mixer.music.load('resources/sounds/music.mp3')
pygame.mixer.music.set_volume(0.5)

Puis quelques paramètres supplémentaires pour gérer le menu.

# Gère l'écart entre le cadre de sélection et le texte de l'élément
self.paddingx = 8
self.paddingy = 20

# Informe de l'écran actuel affiché
self.start_selected = False
self.settings_selected = False
self.quit_select = False

# Le premier élement sera sélectionné par défaut avec l'index 0.
# Si le second élément est sélectionné l'index passera à 1, etc.
self.index_selected = 0

# Element courant sélectionné
self.current_item = ()

Positionnement des éléments visuels

Ici, l’objectif est de récupérer les données fournies par items et de préparer les éléments menu pour l’affichage si aucun écran est sélectionné.

# init.py

self.menu_items = []

for index, item in enumerate(items):
    label = self.font.render(item, 1, font_color)
    width = label.get_rect().width
    height = label.get_rect().height
    
    # Calcul la position en abscisse de l'élément de menu 
    posx = (self.scr_width / 2) - (width / 2)

    # Calcul la hauteur totale du menu
    t_h = len(items) * height

    # Calcul la position en ordonnée
    posy = (self.scr_height / 2) - (t_h / 2) + (index * height)

    # Ajoute l'élément de menu avec ses dimensions calculées
    self.menu_items.append([item, label, (width, height), (posx, posy)])

Afin de démarrer l’écran menu, ajoutez la méthode suivante dans GameMenu :

def run(self):
    # gère la boucle de menu, par défaut l'écran menu ne s'arrête jamais
    mainloop = True
    while mainloop:
        ...

Par défaut, l’élément sélectionné est le premier.

self.current_item = self.menu_items[self.index_selected]

Pour chaque passage dans la boucle de menu, nous affichons le menu et ses éléments.

self.screen.fill(self.bg_color)

if not self.start_selected or not self.settings_selected:
    self.screen.blit(self.bg_img, self.bg_img_rect)

    for name, label, (width, height), (posx, posy) in self.menu_items:
        self.screen.blit(label, (posx, posy))
        name, label, (width, height), (posx, posy) = self.current_item
        pygame.draw.rect(
            self.screen, (255, 255, 255),
            [
                posx - self.paddingx, posy - self.paddingy,
                width + self.paddingx + self.paddingx, height + self.paddingy
            ], 2)

    pygame.display.flip()

Interaction avec l’utilisateur

Pygame récupère les interactions utilisateurs. Notre objectif est de les filtrer et de déclencher une action particulière pour chaque évènement.

Par exemple, quand l’utilisateur appuie sur la touche de clavier ↓ , l’élément de menu sélectionné doit passer au suivant.

Le code suivant doit être placé au début de la boucle. Ainsi, le menu sélectionné sera affiché.

On parcourt les évènements dans une boucle.

for event in pygame.event.get():
    ...

Si l’utilisateur clique sur la croix pour fermer la fenêtre, le jeu s’arrête.

if event.type == pygame.QUIT:
    mainloop = False
    sys.exit()

Sinon si l’utilisateur appuie sur une touche du clavier, on déclenche un évènement particulier.

# ↓ : Sélectionne l'élément suivant si existant
if event.key == pygame.K_UP:
    # Jouer bip de sélection de l'élément
    self.menu_sound.play()
    # Mise à jour de l'index de menu
    for index, item in enumerate(self.menu_items):
        if self.current_item[0] == item[0]:
            if self.index_selected > 0:
	        self.index_selected -= 1

# ↑ : Sélectionne l'élément précèdent si existant
if event.key == pygame.K_DOWN:
    self.menu_sound.play()
    for index, item in enumerate(self.menu_items):
        if self.current_item[0] == item[0]:
            if self.index_selected < (len(self.menu_items) - 1):
	        self.index_selected += 1

En appuyant sur ENTRER, nous souhaitons afficher l’écran sélectionné.

if event.key == pygame.K_RETURN:
    self.valid_menu_sound.play()
    if len(self.current_item) > 0:
        if self.current_item[0] == "Start":
            self.start_selected = True
        elif self.current_item[0] == "Settings":
            self.settings_selected = True
        elif self.current_item[0] == "Quit":
            self.quit_select = True
            pygame.mixer.music.fadeout(1000)
            mainloop = False

.

Félicitations, vous savez maintenant créer un menu de jeu avec Pygame.

Dans la partie suivante, nous créerons la partie la plus importante, l’écran de jeu.

Le code source de ce tutoriel disponible sur le repository git.

Laisser un commentaire