Dans le développement de jeux modernes, la possibilité de sauvegarder et de charger la progression du jeu est une fonctionnalité cruciale qui améliore l’expérience et l’engagement de l’utilisateur. PyGame, une bibliothèque populaire pour la création de jeux 2D en Python, fournit les outils nécessaires pour implémenter la fonction de sauvegarde et de chargement sans effort.
Création d’un jeu simple
Avant de commencer, assurez-vous que pip est installé sur votre appareil. Après avoir installé pip, exécutez la commande suivante pour installer le fichier pygame module :
pip install pygame
Pour illustrer l’implémentation d’un système de sauvegarde et de chargement dans PyGame, commencez par créer un jeu simple.
Le code utilisé dans cet article est disponible dans ce dépôt GitHub et est libre d’utilisation sous la licence MIT.
Dans ce jeu, le joueur aura la possibilité de se déplacer à gauche et à droite. Voici un exemple de code qui démontre la structure de base du jeu :
import pygame
# Initialize Pygame
pygame.init()
# Set up the game window
window_width = 800
window_height = 600
window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("Save and Load System Tutorial")
# Game variables
player_x = 400
player_y = 500
player_speed = 5
# Game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_x -= player_speed
if keys[pygame.K_RIGHT]:
player_x += player_speed
# Clear the screen
window.fill((0, 0, 0))
# Draw the player
pygame.draw.rect(window, (255, 255, 255), (player_x, player_y, 50, 50))
# Update the display
pygame.display.flip()
# Quit the game
pygame.quit()
Gestion de l’état du jeu et de la persistance des données
Avant d’implémenter les fonctionnalités de sauvegarde et de chargement, vous devez trouver un moyen de gérer l’état du jeu et de conserver les données. Une approche courante consiste à utiliser un dictionnaire Python pour stocker les données du jeu. Voici un exemple de la façon dont vous pouvez modifier le code précédent pour inclure la gestion de l’état du jeu :
# Game variables
game_state = {
'player_x': 400,
'player_y': 500
}
# Game loop
running = True
while running:
# ...
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
game_state['player_x'] -= player_speed
if keys[pygame.K_RIGHT]:
game_state['player_x'] += player_speed
# ...
pygame.display.flip()
Implémentation des fonctions de sauvegarde et de chargement
Pour permettre la sauvegarde et le chargement de la progression d’un jeu, vous pouvez utiliser la fonction intégrée de Python pickle qui nous permet de sérialiser et de désérialiser des objets Python. Créez un nouveau fichier nommé save-game.py et ajoutez le code avec les mises à jour ci-dessous :
game_state = {
'player_x': player_x,
'player_y': player_y
}
# Save game state
def save_game_state(game_state, file_name):
try:
with open(file_name, 'wb') as file:
pickle.dump(game_state, file)
print("Game state saved successfully!")
except IOError:
print("Error: Unable to save game state.")
# Load game state
def load_game_state(file_name):
try:
with open(file_name, 'rb') as file:
game_state = pickle.load(file)
print("Game state loaded successfully!")
return game_state
except (IOError, pickle.UnpicklingError):
print("Error: Unable to load game state.")
# Game loop
running = True
while running:
# ...
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_x -= player_speed
game_state['player_x'] = player_x
if keys[pygame.K_RIGHT]:
player_x += player_speed
game_state['player_x'] = player_x
if keys[pygame.K_s]:
save_game_state(game_state, 'save_game.pickle')
if keys[pygame.K_l]:
game_state = load_game_state('save_game.pickle')
player_x = game_state['player_x']
# ...
# ...
Voici le résultat :
Conception d’une interface utilisateur pour la sauvegarde des slots
Pour fournir une interface de sauvegarde et de chargement, vous pouvez afficher des slots de sauvegarde qui permettent au joueur de choisir le slot à sauvegarder ou à charger. Dans cet exemple, les options sont affichées dans la console, mais vous pouvez utiliser les cadres d’interface graphique de Python pour créer une interface plus conviviale.
Créer un save_slots qui représente les emplacements de sauvegarde disponibles. Ajoutez également un élément emplacement_sélectionné variable permettant de garder une trace du slot choisi par le joueur.
Afficher les emplacements de sauvegarde disponibles lorsque le joueur appuie sur le bouton de sauvegarde (K_s). Le joueur peut choisir un emplacement en appuyant sur la touche numérique correspondante (K_1, K_2ou K_3). Si un slot est sélectionné, l’état du jeu est sauvegardé dans un fichier portant le nom du slot sélectionné.
De même, lorsque le joueur appuie sur le bouton de chargement (K_l), affichent les emplacements de sauvegarde. Le joueur peut choisir un emplacement en appuyant sur les touches K_a, K_bou K_c pour charger l’état du jeu. Il est également possible d’utiliser les touches tactiles au lieu des touches du clavier pour la sélection des emplacements. Si un emplacement est sélectionné, l’état du jeu est chargé à partir du fichier correspondant.
Créer un nouveau fichier nommé interface.py et ajoutez le code avec les mises à jour ci-dessous :
# Game variables
save_slots = ['Slot 1', 'Slot 2', 'Slot 3']
selected_slot = None
# Game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
# Show save slots
selected_slot = None
for i, slot in enumerate(save_slots):
print(f"Save Slot {i+1}: {slot}")
print("Choose a slot to save the game.")
if event.key == pygame.K_l:
print("Select Slot:- a - Slot 1 , b - Slot 3, c - Slot 3")
# Show save slots
selected_slot = None
for i, slot in enumerate(save_slots):
print(f"Save Slot {i+1}: {slot}")
print("Choose a slot to load the game.")
if event.key in [pygame.K_1, pygame.K_2, pygame.K_3]:
# Save or load game based on the selected slot
slot_index = event.key - pygame.K_1
selected_slot = save_slots[slot_index]
save_game_state(game_state, f"{selected_slot}.pickle")
print(f"Game saved in {selected_slot}!")
if event.key in [pygame.K_a, pygame.K_b, pygame.K_c]:
slot_index = event.key - pygame.K_a
selected_slot = save_slots[slot_index]
game_state = load_game_state(f"{selected_slot}.pickle")
player_x = game_state['player_x']
print(f"Game loaded from {selected_slot}!")
# ...
pygame.display.flip()
# ...
Voici le résultat :
Gestion des options d’écrasement
Pour fournir des options d’écrasement des sauvegardes existantes, vous pouvez implémenter un message d’avertissement qui invite le joueur à confirmer l’écrasement d’un fichier de sauvegarde. Créez un nouveau fichier nommé overwriting-save.py et modifiez le code avec les mises à jour ci-dessous :
# Save game state
def save_game_state(game_state, file_name):
if os.path.exists(file_name):
# Prompt for confirmation to overwrite existing save file
overwrite = input("Save file already exists. Do you want to overwrite? (y/n): ")
if overwrite.lower() != 'y':
print("Save cancelled.")
return
try:
with open(file_name, 'wb') as file:
pickle.dump(game_state, file)
print("Game state saved successfully!")
except IOError:
print("Error: Unable to save game state.")
# ...
# Load game state
def load_game_state(file_name):
if not os.path.exists(file_name):
print("Error: Save file does not exist.")
return None
try:
with open(file_name, 'rb') as file:
game_state = pickle.load(file)
print("Game state loaded successfully!")
return game_state
except (IOError, pickle.UnpicklingError):
print("Error: Unable to load game state.")
return None
# ...
Dans le code ci-dessus, avant de sauvegarder un état de jeu, on vérifie si le fichier de sauvegarde existe déjà en utilisant la commande os.path.exists(). Si c’est le cas, vous demandez au joueur de confirmer l’écrasement du fichier d’enregistrement existant. Si le lecteur choisit de ne pas écraser le fichier, l’opération de sauvegarde est annulée.
De même, avant de charger un état de jeu, vous vérifiez si le fichier de sauvegarde existe en utilisant la commande os.path.exists(). Si ce n’est pas le cas, vous informez le joueur avec un message d’erreur.
Meilleures pratiques pour le système de sauvegarde et de chargement
Lors de l’implémentation d’un système de sauvegarde et de chargement dans PyGame ou tout autre projet de développement de jeu, prenez en compte les meilleures pratiques suivantes :
- Utiliser une structure de données bien définie pour représenter l’état du jeu et la sérialiser à l’aide d’une bibliothèque de sérialisation telle que pickle. Cela vous permet de sauvegarder et de charger facilement l’état complet du jeu.
- Créez un répertoire ou un dossier dédié pour stocker les fichiers sauvegardés. Cela permet d’organiser les fichiers sauvegardés et d’éviter d’encombrer le répertoire principal du jeu.
- Mettre en place une gestion des erreurs et fournir des messages d’erreur informatifs pour faciliter le débogage et le dépannage. Cela aide les joueurs à comprendre les problèmes qui peuvent survenir pendant les opérations de sauvegarde et de chargement.
- Envisager d’implémenter plusieurs emplacements de sauvegarde pour permettre aux joueurs d’avoir plusieurs sauvegardes de jeu. Cela donne aux joueurs la possibilité d’explorer différents chemins ou de rejouer des sections spécifiques du jeu sans écraser leur progression.
Rendre les jeux plus attrayants grâce à un système de sauvegarde et de chargement
L’ajout d’une fonction de sauvegarde et de chargement peut grandement améliorer l’engagement et le plaisir d’un jeu. Elle permet aux joueurs de sauvegarder leur progression et de revenir au jeu à leur convenance. En outre, elle ouvre la voie à la création d’univers de jeu complexes, dans lesquels les choix et les actions du joueur ont des conséquences durables.
En mettant en place un système de sauvegarde et de chargement, vous pouvez permettre à vos joueurs de vivre une expérience de jeu plus immersive et plus satisfaisante.