JEU DE PACMAN
Partie 3 : Le jeu
------------------------------------------------------------------
Dans le jargon, ce qu'on appele les "tiles" (lire en anglais!) ce sont les images qui sont utilisés pour représenter une case d'un plateau de jeu, c'est ce que l'on a traditionellement dans Zelda par exemple.
Ici, on va afficher chacune des 25x25=625 tiles carrées de 20 pixels (de coté) en fonction des données présente dans notre tableau en deux dimensions "board". Notre plateau sera enfin opérationnel!
Mais il faut tout d'abord créer les sprites des tiles et les inserer dans le dossier de votre projet, les voicis :
0.bmp :
1.bmp :
2.bmp :
3.bmp :
Elles sont très sommaires, oui, mais c'est juste pour faire marcher notre pacman!
C'est parti :
- Code: Tout sélectionner
#include <allegro.h>
#define SIZE 25
// Pour alleger le code :
void exit_on_error(char* error_message)
{
allegro_message(error_message);
exit(-1);
}
// reste inchangé a par la résolution
void init()
{
int res;
allegro_init();
set_color_depth(32);
res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, SIZE*20, SIZE*20, 0, 0);
if (res != 0) exit_on_error("Impossible de charger le mode graphique");
install_timer();
install_keyboard();
}
void deinit()
{
clear_keybuf();
}
int main()
{
// Varibles pour les graphismes
BITMAP *buffer;
BITMAP *tile[4];
//Variables temporaires
int i,j; // pour les boucles for
// Variables du jeu
char quit = 0; // rôle booléen
int board[SIZE][SIZE];
// Initialisation d'Allegro
init();
// Chargement des images des sprites APRES init()
tile[0] = load_bitmap("0.bmp", NULL);
tile[1] = load_bitmap("1.bmp", NULL);
tile[2] = load_bitmap("2.bmp", NULL);
tile[3] = load_bitmap("3.bmp", NULL);
for (i=0;i<4;i++) if (!tile[i]) exit_on_error("Impossible de lire une tile.");
// Création du buffer
buffer = create_bitmap(SIZE*20, SIZE*20);
if (!buffer) exit_on_error("Impossible d'allouer le buffer.");
// Remplissage de board (sans lire un fichier pour le moment)
for (i=0;i<SIZE;i++)
for (j=0;j<SIZE;j++)
board[i][j] = (i+j)%4; // par exemple, juste pour voir nos 4 sprites
while (!quit)
{
if (key[KEY_ESC]) quit = 1;
// On dessine les tiles
for (i=0;i<SIZE;i++)
for (j=0;j<SIZE;j++)
draw_sprite(buffer, tile[board[i][j]], i*20, j*20);
// On balance le tout sur l'écran
blit(buffer, screen, 0, 0, 0, 0, SIZE*20, SIZE*20);
}
// Fin du programme
destroy_bitmap(buffer);
for (i=0;i<4;i++) destroy_bitmap(tile[i]);
return 0;
}
END_OF_MAIN()
Le résultat (très moche certes) :
Alors là c'est du méga brutal, mais je voulais pas me casser la tête, je lis le fichier à l'ancienne : caractère par caractère. Pour des raisons d'évitage de bug, le fichier doit contenir EXACTEMENT SIZE*SIZE (=625 ici) caractères (0, 1, 2 ou 3 cf chapitre 1).
Voici votre fichier "board.txt" (toujours a rajouter dans le dossier de votre projet) : board.txt
ATTENTION : ne pas rajouter d'espaces ou de saut de lignes, même en fin de fichier! (c'est pas ce qu'on peut appeler de la flexibilité mais ça marche! Quitte à créer un éditeur de niveaux plus tard... lol)
Voici le code à inserer dans le main du programme précedant (en enlevant au préalable le remplissage "de test" du tableau board) :
- Code: Tout sélectionner
#include <stdio.h> // A ne pas oublier!
(...)
//Variables temporaires
FILE *board_file;
char c;
(...) // Autres initialisations ici
// Lecture plateau dans "board.txt" qui doit faire EXACTEMENT SIZE*SIZE caractères
board_file = fopen("board.txt", "r");
if (board_file==NULL) exit_on_error("Impossible d'ouvrir \"board.txt\"");
i = 0;
do
{
if (i>SIZE*SIZE) exit_on_error("\"board.txt\" trop long");
c = fgetc(board_file);
switch (c)
{
case '1' : board[i%SIZE][i/SIZE] = 1;
break;
case '3' : board[i%SIZE][i/SIZE] = 3;
break;
case '2' : board[i%SIZE][i/SIZE] = 2;
break;
case '0' : board[i%SIZE][i/SIZE] = 0;
break;
}
i++;
} while (c != EOF);
if (i<=SIZE*SIZE) exit_on_error("\"board.txt\" trop court");
fclose(board_file);
// et hop vous pouvez utiliser votre board !
Je ne m'attarderais pas sur le fonctionnement de la lecture de fichiers mais plutot sur le remplissage du tableau 2D a partir d'un flux de données comme celui du fichier :
- Code: Tout sélectionner
board[i%SIZE][i/SIZE]
- l'opérateur % est le modulo (le reste de la division entière)
- l'opérateur / est la division entière
Pour tout i entier, le modulo "i%n" est un entier compris entre 0 et n-1.
Et on sait (d'après la division euclidienne) que i == n*(i/n) + i%n. Si c'est un peu trop mathématique pour vous, contentez-vous de savoir que par exemple 23%9 == 5 (on enlève le maximum de fois 9 dans 23) et 23/9 == 2 (c'est le nombre de fois qu'on a enlevé 9 de 23). Compris?
Au final, on obtient ce que l'on veut (magie!) :
Voici notre Pacman :
.Pour le moment on va rajouter son affichage dans notre jeu et on va l'orienter selon la flèche du clavier préssée (sans le déplacer pour le moment).
Il existe des fonctions de symétrie horizontale et verticale pour les sprites, on peut aussi en théorie les faire tourner d'un certain angle. En théorie car il s'avère que ces fonctions de rotations ne fonctionnent pas chez moi (ou alors c'est moi qui sait pas les faire fonctionner!). On va donc utiliser un second sprite avec une pré-rotation de 90° :

On va commencer par rajouter plusieurs variables :
- Code: Tout sélectionner
// Varibles pour les graphismes
BITMAP *s_pacman[4];
// Variables du jeu
int pacman_x = 12;
int pacman_y = 16;
int pacman_d = 1;
Le tableau de 4 sprites "s_pacman" représente les quatres orientations de pacman selon sa direction de déplacement. Sa direction de déplacement est stockée dans l'entier "pacman_d" : 0 signifie haut, 1 signifie droite, 2 signifie bas et enfin 3 signifie gauche.
Regardons maintenant la création des deux autres sprites de pacman bas et gauche (on à déjà droite et haut!) :
- Code: Tout sélectionner
s_pacman[0] = load_bitmap("pacman2.bmp", NULL);
s_pacman[1] = load_bitmap("pacman.bmp", NULL);
s_pacman[2] = create_bitmap(20, 20);
s_pacman[3] = create_bitmap(20, 20);
for (i=0;i<4;i++) if (!s_pacman[i]) exit_on_error("Impossible de lire un sprite pacman.");
// "Mirroir" du sprite pacman
draw_sprite_v_flip(s_pacman[2], s_pacman[0], 0, 0);
draw_sprite_h_flip(s_pacman[3], s_pacman[1], 0, 0);
(...)
// Fin du programme
for (i=0;i<4;i++) destroy_bitmap(s_pacman[i]);
L'implémentation de draw_sprite_v_flip (ou h_flip) :
- Code: Tout sélectionner
void draw_sprite_v_flip(BITMAP *bmp, BITMAP *sprite, int x, int y);
Maintenant il nous faut lire le clavier, rien de plus simple, rajouter ce qui suit sous "if (key[KEY_ESC]) quit = 1;" :
- Code: Tout sélectionner
if (key[KEY_UP]) pacman_d = 0;
if (key[KEY_RIGHT]) pacman_d = 1;
if (key[KEY_DOWN]) pacman_d = 2;
if (key[KEY_LEFT]) pacman_d = 3;
Il reste plus qu'a l'afficher, rajouter ce qui suit entre le dessin du plateau et le blit du buffer :
- Code: Tout sélectionner
draw_sprite(buffer, s_pacman[pacman_d], pacman_x*20, pacman_y*20);
Facile non?
Voici le code source complet :
- Code: Tout sélectionner
#include <allegro.h>
#include <stdio.h>
#define SIZE 25
// Pour alleger le code :
void exit_on_error(char* error_message)
{
allegro_message(error_message);
exit(-1);
}
// reste inchangé a par la résolution
void init()
{
int res;
allegro_init();
set_color_depth(32);
res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, SIZE*20, SIZE*20, 0, 0);
if (res != 0) exit_on_error("Impossible de charger le mode graphique");
install_timer();
install_keyboard();
}
void deinit()
{
clear_keybuf();
}
int main()
{
// Varibles pour les graphismes
BITMAP *buffer;
BITMAP *tile[4];
BITMAP *s_pacman[4];
//Variables temporaires
int i,j; // pour les boucles for
FILE *board_file;
char c;
// Variables du jeu
char quit = 0; // rôle booléen
int pacman_x = 12;
int pacman_y = 16;
int pacman_d = 1;
int board[SIZE][SIZE];
// Initialisation d'Allegro
init();
// Chargement des images et buffer
buffer = create_bitmap(SIZE*20, SIZE*20);
if (!buffer) exit_on_error("Impossible d'allouer le buffer.");
tile[0] = load_bitmap("0.bmp", NULL);
tile[1] = load_bitmap("1.bmp", NULL);
tile[2] = load_bitmap("2.bmp", NULL);
tile[3] = load_bitmap("3.bmp", NULL);
for (i=0;i<4;i++) if (!tile[i]) exit_on_error("Impossible de lire une tile.");
s_pacman[0] = load_bitmap("pacman2.bmp", NULL);
s_pacman[1] = load_bitmap("pacman.bmp", NULL);
s_pacman[2] = create_bitmap(20, 20);
s_pacman[3] = create_bitmap(20, 20);
for (i=0;i<4;i++) if (!s_pacman[i]) exit_on_error("Impossible de lire un sprite pacman.");
// "Mirroir" du sprite pacman
draw_sprite_v_flip(s_pacman[2], s_pacman[0], 0, 0);
draw_sprite_h_flip(s_pacman[3], s_pacman[1], 0, 0);
// Chargement du plateau
board_file = fopen("board.txt", "r");
if (bf==NULL) exit_on_error("Impossible d'ouvrir \"board.txt\"");
i = 0;
do
{
if (i>SIZE*SIZE) exit_on_error("\"board.txt\" trop long");
c = fgetc(board_file);
switch (c)
{
case '1' : board[i%SIZE][i/SIZE] = 1;
break;
case '3' : board[i%SIZE][i/SIZE] = 3;
break;
case '2' : board[i%SIZE][i/SIZE] = 2;
break;
case '0' : board[i%SIZE][i/SIZE] = 0;
break;
}
i++;
} while (c != EOF);
if (i<=SIZE*SIZE) exit_on_error("\"board.txt\" trop court");
fclose(board_file);
// Début du jeu
while (!quit)
{
if (key[KEY_ESC]) quit = 1;
if (key[KEY_UP]) pacman_d = 0;
if (key[KEY_RIGHT]) pacman_d = 1;
if (key[KEY_DOWN]) pacman_d = 2;
if (key[KEY_LEFT]) pacman_d = 3;
// On dessine les tiles
for (i=0;i<SIZE;i++)
for (j=0;j<SIZE;j++)
draw_sprite(buffer, tile[board[i][j]], i*20, j*20);
// On dessine pacman
draw_sprite(buffer, s_pacman[pacman_d], pacman_x*20, pacman_y*20);
// On balance le tout sur l'écran
blit(buffer, screen, 0, 0, 0, 0, SIZE*20, SIZE*20);
}
// Fin du programme
destroy_bitmap(buffer);
for (i=0;i<4;i++)
{
destroy_bitmap(tile[i]);
destroy_bitmap(s_pacman[i]);
}
deinit();
return 0;
}
END_OF_MAIN()
Et le résultat avec notre pacman qui regarde suivant la fleche sur laquelle on appuye :
:arrow: Pacman a faim et veut des jambes :
Tout d'abord comptons combien on a de boules et de bonus sur le plateau en modifiant la lecture du fichier :
- Code: Tout sélectionner
// Variables de jeu
int nb_boules = 0;
int nb_bonus = 0;
(...)
switch (c)
{
case '1' : board[i%SIZE][i/SIZE] = 1;
nb_boules++;
break;
case '3' : board[i%SIZE][i/SIZE] = 3;
break;
case '2' : board[i%SIZE][i/SIZE] = 2;
nb_bonus++;
break;
case '0' : board[i%SIZE][i/SIZE] = 0;
break;
}
(...)
Rien a dire ici! On affichera a l'écran ces deux entiers plus tard...
Pour déplacer votre pacman il suffit "simplement" de rajouter ce code a la place de la lecture clavier avant les dessins :
- Code: Tout sélectionner
if (key[KEY_ESC]) {quit = true; break;}
if (key[KEY_UP]) if (board[pacman_x][pacman_y-1] != 3) pacman_d = 0;
if (key[KEY_RIGHT]) if (board[pacman_x+1][pacman_y] != 3) pacman_d = 1;
if (key[KEY_DOWN]) if (board[pacman_x][pacman_y+1] != 3) pacman_d = 2;
if (key[KEY_LEFT]) if (board[pacman_x-1][pacman_y] != 3) pacman_d = 3;
// On va sortir du plateau? -> déplacement automatique
if (pacman_x == 0 && pacman_d == 3) pacman_x = SIZE-1;
else if (pacman_y == 0 && pacman_d == 0) pacman_y = SIZE-1;
else if (pacman_x == SIZE-1 && pacman_d == 1) pacman_x = 0;
else if (pacman_y == SIZE-1 && pacman_d == 2) pacman_y = 0;
else // Sinon déplacement normal de pacman
switch (pacman_d)
{
case 0 : if (board[pacman_x][pacman_y-1] != 3) pacman_y--; break;
case 1 : if (board[pacman_x+1][pacman_y] != 3) pacman_x++; break;
case 2 : if (board[pacman_x][pacman_y+1] != 3) pacman_y++; break;
case 3 : if (board[pacman_x-1][pacman_y] != 3) pacman_x--; break;
};
C'est pas très joli mais c'est efficace!
Maintenant il faut le faire manger, rajoutez ceci juste après le code précedant :
- Code: Tout sélectionner
// Manger !
switch (board[pacman_x][pacman_y])
{
case 1 : board[pacman_x][pacman_y] = 0;
nb_boules--;
break;
case 2 : board[pacman_x][pacman_y] = 0;
nb_bonus--;
break;
}
if (nb_boules == 0 && nb_bonus == 0) quit = 1;
Pas de commentaires particuliers, avec un peu de réflexion ce code est assez simple. Mais il a été fait de sorte que quand vous appuyez dans une direction impossible pacman ne se stop pas et ne passe pas un tour de jeu sans bouger.
Vous pouvez compiler, vous avez un super pacman qui mange (et le jeu se termine quand vous avez tout mangé)... MAIS, gros probleme, le jeu va trop vite!!!
Alors on est ici dans un point critique du jeu, la temporisation!
Je vous rapelle le schéma du moteur de jeu :

Le principe de notre timer est d'attendre que sufissament de temps se soit passé pour faire avancer et redessiner le jeu. Certes, mais une chose important est que durant cette phase d'attente nous lisions le clavier (sinon vous avez une chance infime d'appuyer sur la touche quand le programme fait son test). On va donc insérer un boucle "d'attente" qui se contentera de lire le clavier en permanence, puis on en sortira en temps venu!
Mettons en place ce fameux timer (de façon bizarre car très proche de la machine!).
Rajoutez ce code au début, en dehors de votre fonction main :
- Code: Tout sélectionner
#define TIME_COUNT 10; // Réduire pour accelerer le jeu
volatile int timer=0; // Pour la temporisation
void incrementer_timer()
{
timer++;
}
END_OF_FUNCTION(incrementer_timer);
Le volatile et cette fonction triviale sont présent pour des raisons machines pronfondes.
Ce qu'il vous faut savoir c'est que cette fonction incrementer_timer sera appelée a des intervalles réguliers (que l'on choisira plus loin), mais on a pas le droit de mettre nos procedures de dessin dedans, il faut qu'elle reste très très très simple.
Rajoutez ceci dans main() :
- Code: Tout sélectionner
// Variables du jeu
int next_time = 0;
Rajoutez ceci à la fin de init() :
- Code: Tout sélectionner
LOCK_VARIABLE(timer);
LOCK_FUNCTION(incrementer_timer);
install_int_ex(incrementer_timer, BPS_TO_TIMER(60));
- Code: Tout sélectionner
remove_int(incrementer_timer);
Et pour terminer, la boucle d'attente dans le corps du jeu :
- Code: Tout sélectionner
// Boucle "d'attente"
while(timer<next_time)
{
if (key[KEY_ESC]) {quit = true; break;}
if (key[KEY_UP]) if (board[pacman_x][pacman_y-1] != 3) pacman_d = 0;
if (key[KEY_RIGHT]) if (board[pacman_x+1][pacman_y] != 3) pacman_d = 1;
if (key[KEY_DOWN]) if (board[pacman_x][pacman_y+1] != 3) pacman_d = 2;
if (key[KEY_LEFT]) if (board[pacman_x-1][pacman_y] != 3) pacman_d = 3;
}
next_time = timer + TIME_COUNT;
BPS_TO_TIMER(60) signifie que la fonction increment_timer sera appelée 60 fois par secondes, donc que timer est incrémenté de 60 toutes les secondes. Ensuite il faut juste savoir que la boucle d'attente tournera pendant TIME_COUNT unités de temps, ici le jeu tournera théoriquement a 6 images par secondes car TIME_COUNT vaut 10 (peut-être un peu moin dans la pratique).
Afficher un texte et des variables avec Allegro est un vrai jeu d'enfant, rajoutez ce code avant le blit du dessin (n'hésitez pas a consulter la documentation de la librairie) :
- Code: Tout sélectionner
// Variables temporaires
blanc = makecol32(255,255,255);
gris = makecol32(128,128,128);
(...)
// A rajouter avant le "blit"
textprintf_ex(buffer, font, 0, 0, blanc, gris, "Pacman par Mandibull");
textprintf_ex(buffer, font, 0, 10, blanc, gris, "Boules : %i Bonus : %i", nb_boules, nb_bonus);
Enfin, un dernier détail facultatif, pour accelerer les acces répétés a un bitmap (ici buffer) :
- Code: Tout sélectionner
acquire_bitmap(buffer);
// Avec ici tout le dessin dans buffer
release_bitmap(buffer);
// Et là le blit...
Vous avez pas bien suivi? Voici le code source complet :
- Code: Tout sélectionner
#include <allegro.h>
#include <stdio.h> // Pour la lecture de fichier
#define SIZE 25
#define TIME_COUNT 10; // Réduire pour accelerer le jeu
volatile int timer=0; // Pour la temporisation
void incrementer_timer()
{
timer++;
}
END_OF_FUNCTION(incrementer_timer);
// Pour alleger le code :
void exit_on_error(char* error_message)
{
allegro_message(error_message);
exit(-1);
}
// reste inchangé a par la résolution
void init()
{
int res;
allegro_init();
set_color_depth(32);
res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, SIZE*20, SIZE*20, 0, 0);
if (res != 0) exit_on_error("Impossible de charger le mode graphique");
install_timer();
install_keyboard();
LOCK_VARIABLE(timer);
LOCK_FUNCTION(incrementer_timer);
install_int_ex(incrementer_timer, BPS_TO_TIMER(60));
}
void deinit()
{
remove_int(incrementer_timer);
clear_keybuf();
}
int main()
{
// Varibles pour les graphismes
BITMAP *buffer;
BITMAP *s_pacman[4];
BITMAP *tile[4];
//Variables temporaires
FILE *bf;
char c;
int i,j;
int blanc, gris;
// Variables du jeu
int next_time = 0;
bool quit = false;
int board[SIZE][SIZE];
int pacman_x = 12; // Position de pacman (pos initiale : 12,16)
int pacman_y = 16;
int pacman_d = 0; // Direction de pacman 0=haut, 1=droite, 2=bas, 3=gauche
int nb_boules = 0;
int nb_bonus = 0;
// Initialisation d'Allegro et du timer
init();
// Lecture plateau dans "board.txt" qui doit faire EXACTEMENT SIZE*SIZE caractères
bf = fopen("board.txt", "r");
if (bf==NULL) exit_on_error("Impossible d'ouvrir \"board.txt\"");
i = 0;
do
{
if (i>SIZE*SIZE) exit_on_error("\"board.txt\" trop long");
c = fgetc(bf);
switch (c)
{
case '1' : board[i%SIZE][i/SIZE] = 1;
nb_boules++;
break;
case '3' : board[i%SIZE][i/SIZE] = 3;
break;
case '2' : board[i%SIZE][i/SIZE] = 2;
nb_bonus++;
break;
case '0' : board[i%SIZE][i/SIZE] = 0;
break;
}
i++;
} while (c != EOF);
if (i<=SIZE*SIZE) exit_on_error("\"board.txt\" trop court");
fclose(bf);
// Chargement des sprites et création du buffer
buffer = create_bitmap(SIZE*20, SIZE*20);
if (!buffer) exit_on_error("Impossible d'allouer le buffer.");
s_pacman[0] = load_bitmap("pacman2.bmp", NULL);
s_pacman[1] = load_bitmap("pacman.bmp", NULL);
s_pacman[2] = create_bitmap(20, 20);
s_pacman[3] = create_bitmap(20, 20);
for (i=0;i<4;i++) if (!s_pacman[i]) exit_on_error("Impossible de lire un sprite pacman.");
tile[0] = load_bitmap("0.bmp", NULL);
tile[1] = load_bitmap("1.bmp", NULL);
tile[2] = load_bitmap("2.bmp", NULL);
tile[3] = load_bitmap("3.bmp", NULL);
for (i=0;i<4;i++) if (!tile[i]) exit_on_error("Impossible de lire une tile.");
// "Mirroir" du sprite pacman
draw_sprite_v_flip(s_pacman[2], s_pacman[0], 0, 0);
draw_sprite_h_flip(s_pacman[3], s_pacman[1], 0, 0);
// Dernier détail
blanc = makecol32(255,255,255);
gris = makecol32(128,128,128);
// Le jeu!
while (!quit)
{
// Boucle "d'attente"
while(timer<next_time)
{
if (key[KEY_ESC]) {quit = true; break;}
if (key[KEY_UP]) if (board[pacman_x][pacman_y-1] != 3) pacman_d = 0;
if (key[KEY_RIGHT]) if (board[pacman_x+1][pacman_y] != 3) pacman_d = 1;
if (key[KEY_DOWN]) if (board[pacman_x][pacman_y+1] != 3) pacman_d = 2;
if (key[KEY_LEFT]) if (board[pacman_x-1][pacman_y] != 3) pacman_d = 3;
}
next_time = timer + TIME_COUNT;
// On va sortir du plateau? -> déplacement automatique
if (pacman_x == 0 && pacman_d == 3) pacman_x = SIZE-1;
else if (pacman_y == 0 && pacman_d == 0) pacman_y = SIZE-1;
else if (pacman_x == SIZE-1 && pacman_d == 1) pacman_x = 0;
else if (pacman_y == SIZE-1 && pacman_d == 2) pacman_y = 0;
else // Sinon déplacement normal de pacman
switch (pacman_d)
{
case 0 : if (board[pacman_x][pacman_y-1] != 3) pacman_y--; break;
case 1 : if (board[pacman_x+1][pacman_y] != 3) pacman_x++; break;
case 2 : if (board[pacman_x][pacman_y+1] != 3) pacman_y++; break;
case 3 : if (board[pacman_x-1][pacman_y] != 3) pacman_x--; break;
};
// Manger !
switch (board[pacman_x][pacman_y])
{
case 1 : board[pacman_x][pacman_y] = 0;
nb_boules--;
break;
case 2 : board[pacman_x][pacman_y] = 0;
nb_bonus--;
break;
}
if (nb_boules == 0 && nb_bonus == 0) quit = 1;
// DESSINS
acquire_bitmap(buffer); // petit détail pour les perfs graphiques
// Dessin du plateau
for (i=0;i<SIZE;i++)
for (j=0;j<SIZE;j++)
draw_sprite(buffer, tile[board[i][j]], i*20, j*20);
// Dessin de pacman suivant sa direction
draw_sprite(buffer, s_pacman[pacman_d], pacman_x*20, pacman_y*20);
textprintf_ex(buffer, font, 0, 0, blanc, gris, "Pacman par Mandibull");
textprintf_ex(buffer, font, 0, 10, blanc, gris, "Boules : %i Bonus : %i", nb_boules, nb_bonus);
release_bitmap(buffer); // va avec acquire_bitmap
// On balance le tout sur l'écran
blit(buffer, screen, 0, 0, 0, 0, SIZE*20, SIZE*20);
}
// On détruit tout!
deinit();
destroy_bitmap(buffer);
for (i=0;i<4;i++)
{
destroy_bitmap(tile[i]);
destroy_bitmap(s_pacman[i]);
}
return 0;
}
END_OF_MAIN()
et le résultat :
Rendez-vous partie 4!





