So Long

Petit jeu 2D développé en C avec la MiniLibX : le joueur collecte tous les objets d'un labyrinthe puis atteint la sortie.
Présentation
Un jeu 2D en labyrinthe où l'on déplace un personnage tuile par tuile : ramasser tous les objets, éviter les murs (et le slime en bonus), puis sortir par la porte une fois le niveau nettoyé.
Contexte
Projet de la branche graphique du tronc commun 42 : prendre en main la MiniLibX (bibliothèque X11 fournie par l'école) pour gérer une fenêtre, charger des sprites, capter les événements clavier/souris et afficher un rendu fluide.
Projet réalisé en solo, en janvier 2023, avec une version bonus complète.
Mon rôle
Développeur solo sur l'ensemble du projet :
- Partie obligatoire : parsing des cartes
.ber, validation du chemin, rendu et gestion des événements - Partie bonus : ennemi slime, écrans de victoire et game over, sprites animés et compteurs affichés à l'écran
Architecture
Le jeu se déroule en deux temps : une validation complète de la carte avant d'ouvrir la fenêtre, puis une boucle d'événements MiniLibX qui redessine les tuiles à chaque déplacement.
| Étape | Rôle | Dans le code |
|---|---|---|
| Lecture & vérifs | Ouverture du fichier .ber, extension valide, argc | open_file() (so_long_utils.c) |
| Parsing | Caractères autorisés, bordures fermées, 1 joueur, 1 sortie, ≥ 1 objet | ft_parsing.c |
| Chemin | Copie de la carte (duplicate_map) + flood-fill récursif depuis le joueur | ft_parse_road.c |
| Fenêtre & sprites | mlx_new_window, chargement des images XPM 64×64 | ft_inits.c |
| Boucle de jeu | Hooks clavier + fermeture fenêtre, déplacements | main.c, ft_move.c, ft_event_move.c |
| Rendu | Affichage tuile par tuile dans la fenêtre | ft_display.c |
| Bonus | Slime, animations, compteurs à l'écran | so_long_bonus/ |
Technologies
C
Norme 42, compilé avec clang et les flags -Wall -Wextra -Werror.
Makefile
Règles all, bonus, clean, fclean, re.
MiniLibX (X11)
Vendue dans le dépôt (mlx_linux/), compilée par le Makefile.
Sprites XPM
Images 64×64 (PIXEL 64), chargées via mlx_xpm_file_to_image.
Cartes .ber
Validation stricte : murs sur les bordures, unicité du joueur et de la sortie, au moins un objet.
Flood-fill récursif
Vérifie que tous les objets et la sortie sont atteignables.
Ennemi slime
Symbole M, le toucher déclenche un game over.
Affichage HUD
Compteurs d'objets et de mouvements via mlx_string_put.
Fonctionnalités
- Cartes
.ber: validation du format (extension, caractères0/1/E/C/P), des bordures, de l'unicité dePetE, et présence d'au moins un objet - Vérification de chemin : flood-fill récursif garantissant l'accès à tous les objets et à la sortie
- Déplacements au clavier :
ZQSD(clavier AZERTY) /WASD(partie obligatoire), flèches directionnelles (bonus) - Collecte et sortie : la porte ne s'ouvre qu'une fois tous les objets ramassés
- Compteur de mouvements incrémenté à chaque déplacement
- Fermeture propre : touche
Échapou croix de la fenêtre, avec libération de la mémoire - Bonus : ennemi slime (
M) → game over, écran de victoire, sprites du joueur orientés, animation des objets collectés, compteurs affichés à l'écran
Problème | Solution
| Problème | Solution |
|---|---|
| Des cartes invalides doivent être refusées proprement | Validation en plusieurs passes (ft_parsing.c) avec messages Error sur stderr et libération de la mémoire |
| Un objet ou la sortie peut être bloqué par des murs | Flood-fill récursif sur une copie de la carte (duplicate_map) : toute case C/E non atteinte entraîne une erreur |
| Fermer le jeu sans fuite de mémoire | ft_close / ft_error : destruction des images, de la fenêtre et libération du tableau de la carte |
| Afficher un labyrinthe fluide | Rendu tuile par tuile en mlx_put_image_to_window, sprites 64×64 préchargés |
Résultats
- Deux binaires compilés :
so_long(partie obligatoire) etsolong_bonus(bonus) - Boîte d'erreurs complète qui refuse toute carte invalide sans crasher
- Cinq cartes de test fournies (dont deux pour le bonus avec ennemis)
- Bonus complet : game over, victoire, compteurs à l'écran
Lancement
make # compile so_long (partie obligatoire)
make bonus # compile solong_bonus (partie bonus)
./so_long carte_01.ber # partie obligatoire
./solong_bonus carte_03_bonus.ber # partie bonus
Tests & Visualisation
Version Standard
Version Bonus
Ce que j'ai appris
so_long m'a appris à réfléchir en tuiles : chaque déplacement est une simple opération sur un tableau 2D char, et l'écran n'est qu'une projection de cette matrice sur la fenêtre.
Le flood-fill a été mon premier vrai algorithme de graphe : transformer une carte en problème d'accessibilité (toutes les cases C et E sont-elles reliées à P ?) m'a fait comprendre la différence entre vérifier les caractères et vérifier la topologie de la carte.
J'ai aussi découvert la discipline de la gestion mémoire avec MiniLibX : chaque mlx_xpm_file_to_image demande un mlx_destroy_image, et une fenêtre qui ne se ferme pas proprement est une fuite visible au valgrind.