JEU DE PACMAN
Partie 1 : Introduction et mise en place
------------------------------------------------------------------
Le but de ce tutorial est de créer un jeu de pacman pour windows (que l'on expliquera pas ici!) en C.
La programmation windows "pûre", c'est à dire via l'API WIN32, étant vraiment trop complexe et peu flexible, elle sera contournée grâce à la librairie Allegro (spécialement conçue pour la création de "petit" jeux, et vous permettra d'acquérir les principes de la création de jeux).
Notons que Allegro est portable sur (presque toutes) les plateformes sans trop de mal (dont Linux et OS X).
On abordera pas ici le C++ et la POO (Programmation Orientée Objet), qui ne sont pas nécessaires et surtout qui compliquerait la compréhension pour les néophites, pourtant une telle architecture est souvent indispensable dès que le jeu prend du volume!
Contrainte : le jeu se déroulera "case par case" c'est a dire que les positions seront repérés par des coordonnées entières, comme dans un tableau, donc on aura pas de problèmes complexes de collisions.
:arrow: Pré-requis et logiciels utilisés :
- Une (bonne) connaissance du langage C et un minimum de pratique!
- Dev-C++ (version 5 beta : devcpp-4.9.9.2_setup.exe)
- Allegro (pour Dev-C++) (allegro-4.2.0-1mol.DevPak)
Installez d'abord Dev-C++ un IDE (environnement de développement) C/C++ libre et gratuit puis double cliquez sur votre fichier Allegro ".DevPak" et laissez l'installation par défaut se faire (et n'oubliez pas de mettre Dev-C++ en français).
Aussi, durant tout ce tutorial n'hésitez pas a aller consulter la documentation Allegro (en anglais).
:arrow: Moteur de jeu :
Alors nous voici directement dans le coeur du fonctionnement d'un jeu. Je vais expliquer brièvement le principe de notre moteur pacman grâce a un diagramme :

On remparlera de son implémentation plus tard.
Initialisations contiendra l'initialisation d'Allegro(graphismes), du clavier et du timer, la création de toutes nos variables (dont celles du jeu) et surtout le chargement des images et du plateau. Les erreurs lors de l'initialisation sont principalement : fichier manquant, manque de mémoire ou impossibilité d'initialiser le mode graphique.
La partie suivante est une boucle while :
- Code: Tout sélectionner
char quit = 0;
(...)
while (!quit)
{
// On insère ici la lecture clavier, le timer, les calculs et l'affichage !
}
Si le jeu est fini ou si l'on presse la touche Echap il suffira de faire "quit = 1; n'importe où dans notre boucle".
Ce que j’ai appelé timer est fondamental et peut avoir deux sens distincts :
- On attend que suffisamment de temps se soit écoulé pour réafficher l’image suivante où les personnages ont bougés. (c'est ici le cas)
- On affiche un maximum d’images et on déplace les personnages en fonction du temps écoulé entre deux images (c’est le cas de tout les jeux modernes, on parle de "frames" (images) par seconde).
(Notez que sans temporisation la vitesse du jeu serait proportionelle à celle du processeur... plutôt génant!)
:arrow: Les personnages :
Pacman et les fantômes seront repérés via leur coordonnées entières x et y (abscisse et ordonnée) avec pour origine 0,0 en haut a gauche (bien sur x et y seront positif!).
Leurs déplacements se feront a la phase "calculs", en considérant ce qui a été lu par le clavier pour pacman et l'intelligence articficielle (IA, plus ou moin évoluée) pour les fantomes. Mais ne vous affolez pas l'IA est le cadet de nos soucis ici, pourtant c'est la partie la plus complexe! (avec utilisation d'algorithmes du plus court chemin pourquoi pas...)
:arrow: Le plateau :
Il sera représenté sous forme d’un tableau d’entiers de deux dimensions (25x25 ici). On attribuera différentes valeurs aux cases selon leur contenu.
0 : case vide (ie. sans boule)
1 : case où une boule (que pacman mange) est présent
2 : case où un bonus (pour manger les fantômes) est présent
3 : mur
Voici une image du plateau que l'on va faire (provenant d'un autre jeu) :

Et voici sa représentation en mode texte (pas bien lisible certes, mais ce que l'on stockera en mémoire en le lisant à partir d'un fichier texte) :
- Code: Tout sélectionner
3 3 3 3 3 3 3 3 3 3 3 3 1 3 3 3 3 3 3 3 3 3 3 3 3
3 1 2 1 1 1 1 1 1 1 1 3 1 3 1 1 1 1 1 1 1 1 2 1 3
3 1 3 3 3 3 1 3 3 3 1 3 1 3 1 3 3 3 1 3 3 3 3 1 3
3 3 3 3 3 1 3 3 3 1 3 1 3 1 3 3 3 1 3 3 3 3 1 3 3
3 1 3 3 3 3 1 3 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 1 3
3 1 2 1 1 1 1 3 3 3 3 3 1 3 3 3 3 3 1 1 1 1 2 1 3
3 1 3 3 3 3 1 3 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 1 3
3 1 3 3 3 3 1 3 3 3 1 3 3 3 1 3 3 3 1 3 3 3 3 1 3
3 1 1 1 1 1 1 3 3 3 1 3 3 3 1 3 3 3 1 1 1 1 1 1 3
3 3 3 3 3 3 1 3 3 3 1 3 3 3 1 3 3 3 1 3 3 3 3 3 3
3 3 3 3 3 3 1 3 3 3 1 3 3 3 1 3 3 3 1 3 3 3 3 3 3
3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3
1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1
3 3 3 3 3 3 1 3 3 3 3 3 3 3 3 3 3 3 1 3 3 3 3 3 3
3 3 3 3 3 3 1 3 3 3 3 3 3 3 3 3 3 3 1 3 3 3 3 3 3
3 3 3 3 3 3 1 1 1 1 1 3 3 3 1 1 1 1 1 3 3 3 3 3 3
3 1 2 1 1 1 1 3 3 3 1 1 1 1 1 3 3 3 1 1 1 1 2 1 3
3 1 3 3 3 3 3 3 3 3 1 3 3 3 1 3 3 3 3 3 3 3 3 1 3
3 1 3 3 3 3 3 3 3 3 1 3 3 3 1 3 3 3 3 3 3 3 3 1 3
3 1 1 1 1 1 1 1 1 1 1 3 3 3 1 1 1 1 1 1 1 1 1 1 3
3 1 3 3 3 3 3 3 3 3 1 1 1 1 1 3 3 3 3 3 3 3 3 1 3
3 1 3 3 3 3 3 3 3 3 1 3 1 3 1 3 3 3 3 3 3 3 3 1 3
3 1 2 1 3 3 3 3 3 3 1 3 1 3 1 3 3 3 3 3 3 1 2 1 3
3 3 3 1 1 1 1 1 1 1 1 3 1 3 1 1 1 1 1 1 1 1 3 3 3
3 3 3 3 3 3 3 3 3 3 3 3 1 3 3 3 3 3 3 3 3 3 3 3 3
L'implémentation sera faite comme cela :
- Code: Tout sélectionner
#define SIZE 25
(...)
int board[SIZE][SIZE];
NB : n'oubliez pas que les tableaux commencent à l'indice 0 et finissent à l'indice SIZE-1 ! Si vous dépassez cette limite vous risquez d'avoir des problemes !
Bien sur l’affichage sur écran sera fait via des « sprites » (nom que l’on donne aux images affichées dans les jeux représentant des entités : fond, personnages, objets...) carrés ici dont on reparlera en temps venu au Chapitre 2.
Vous remarquerez aussi la présence de bords "ouverts" où l'on pourra se téléporter de l'autre coté du plateau de jeu.
:arrow: Creation du projet :
Démarrez Dev-C++...

Faites Fichier->Nouveau->Projet
Cliquez sur l'onglet "MultiMedia" et choisissez "Allegro application (static)" (cochez eventuellement "Projet C" mais ce n'est pas nécessaire) enfin entrez le nom de votre projet : "Pacman".
Cliquez sur ok choisissez d'enregistrer "Pacman.dev" dans un nouveau dossier "Pacman".
Vous voici en présence du code de base pour l'utilisation d'Allegro suivant :
- Code: Tout sélectionner
#include <allegro.h>
void init();
void deinit();
int main() {
init();
while (!key[KEY_ESC]) {
/* put your code here */
}
deinit();
return 0;
}
END_OF_MAIN()
void init() {
int depth, res;
allegro_init();
depth = desktop_color_depth();
if (depth == 0) depth = 32;
set_color_depth(depth);
res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
if (res != 0) {
allegro_message(allegro_error);
exit(-1);
}
install_timer();
install_keyboard();
install_mouse();
/* add other initializations here */
}
void deinit() {
clear_keybuf();
/* add other deinitializations here */
}
Je vais réorganiser ce code (assez intuitif) à ma façon (et le commenter sommairement) :
- Code: Tout sélectionner
#include <allegro.h> // Normal !
void init()
{
int res; // res pour résultat
allegro_init(); // initialisation d'Allegro
set_color_depth(32);
res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
if (res != 0) // si l'initialisation du mode graphique se passe mal
{
allegro_message(allegro_error); // message d'erreur
exit(-1); // on quitte le programme avec en retour la valeur -1 qui signifie erreur
}
install_timer(); // timer qui servira pour notre fameuse temporisation
install_keyboard(); // clavier
}
void deinit()
{
clear_keybuf(); // on vide le buffer clavier (détail)
}
int main()
{
init(); // initialisations pour Allegro
while (1)
{
if (key[KEY_ESC]) break; // si touche échape appuyée on sort de la boucle infinie
}
deinit();
return 0; // on quitte le programme avec la valeur de retour 0 : RAS
}
END_OF_MAIN() // commande singulière spécifique à Allegro qui lui signale
// la fin du main et donc qu'il doit s'arreter
Attardons nous sur
- Code: Tout sélectionner
set_color_depth(32);
res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
- set_color_depth permet de choisir la "profondeur" (ou le nombre) de couleurs, le plus naturel étant que ce soit la même que celle de Windows. 32 signifie 32bit (et donc 2^32 = 4294967296 couleurs théoriques), c'est ce que l'on trouve sur tout les ordinateurs de nos jours, c'est pour cela que je me suis permi d'enlever le test crée par Allegro par défaut.
- set_gfx_mode initialise l'instance graphique. Ca crée, en quelque sorte, un lien entre une zone mémoire dite buffer (ou l'on dessinera nos sprites) et la carte graphique (et donc l'écran).
Le mot clef GFX_AUTODETECT_WINDOWED signifie que l'on veut une fenêtre et pas le mode plein-écran, vous pouvez mettre GFX_AUTODETECT_FULLSCREEN si ça vous chante mais ça risque de pas aller si vous choisissez des résolutions "exotiques" (par exemple 500x500 que l'on utilisera probablement).
640 et 480 sont, vous l'aurez compris, respectivement la largeur et la hauteur en pixel de votre zone graphique.
Les deux 0 sont la zone graphique "supplémentaire" toujours plus grande que celle de la zone graphique qui permet d'avoir un "scrolling" (défilement) matériel de votre monde représenté comme une très grande image (comme dans Mario par exemple). On ne s'en servira pas dans pacman.
- Code: Tout sélectionner
Illustration de la mémoire si l'on fait, par exemple,
set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 1024, 1024);
(0,0)------------(640,0)----(1024,0)
| | |
| écran visible | |
| | |
(0,480)----------(640,480) |
| |
| reste de la mémoire vidéo |
| |
(0,1024)--------------------(1024,1024)
Faites Exécuter->Compiler (tout se passe bien normalement) puis Exécuter->Exécuter et vous obtenez ça :
Et on quitte le jeu avec la touche "Echap" au cas ou vous n'auriez pas suivi !
Rendez-vous partie 2 !



