Voici un petit jeu programmé en C avec les librairies tierces SDL, FMOD et TTF.
La gestion du mot à trouvé se fait à l'aide d'un fichier contenant ici 100 mots. Bien évidemment, il est possible d'en ajouter, mais il faudra changer la valeur d'un des DEFINE dans le code (MAX_POSITION).
La bande son du jeu est une musique libre de droit, téléchargée sur le site
http://www.jamendo.com, et les sons dans le jeu sont téléchargés sur le site
http://www.findsounds.com (ce sont aussi des sons libre de droit).
Ce jeu est réalisé dans le cadre d'un examen (pour le graduat informatique) et est un bon exemple de l'utilisation de la SDL, ainsi que FMOD et TTF.
Dernière remarque, ce code est compiler avec Dev C++.
Ayant une archive compressé de plus de 1mo (10.4 Mo ici), je ne peux la faire télécharger par le biais de ce site. Cependant, si vous le désirez, vous pouvez télécharger l'archive contenant le code source et l'exécutable ici :
http://mypictures.site.voila.fr/pendu.zip
Source / Exemple :
/********************************************************************
Fichier : main.c
Auteur : Haimet Stéphane
Crée le 19/11/08 à 18h05
modifié le 30/11/08 à 19h29
Description : Réalisation d'un jeu de pendu en 2D
utilisant les librairies tierces SDL pour la gestion de la 2D,
FMOD (pour la gestion du son) et la TTF pour la gestion
du texte, on a donc aussi la présence de plusieurs DLL dans
le répertoire où ce fichier se trouve.
#include <stdlib.h>
#include <stdio.h>
#include <string.h> //Contient des fonctions pour les chaines
#include <SDL/SDL.h> //Contient les fonctions de la SDL
#include <FMOD/fmod.h> //Contient les fonctions de sonorité (FMOD)
#include <SDL/SDL_ttf.h> //Contient les fonctions pour la gestion du texte
//On crée des defines
#define MIN_POSITION 1 //Utilisé pour le random (selection d'un mot dans le dictionnaire
#define MAX_POSITION 100 //Nombre maxi de mot dans le dictionnaire
//PROTOTYPES DES FONCTIONS
void creerMotSecret(char *mot);
void choixDeLAcceuil(SDL_Surface *ecran);
int jouer(SDL_Surface *ecran);
char recupererLettre(FSOUND_SAMPLE *erreur);
void afficherEcranJeu(SDL_Surface *ecran,SDL_Surface *fondJeu, int longueur, char *motSecret, int coupFoireux, int *emplacementTrouve);
int verificationLettreEntree(char *motSecret,int *emplacementTrouve,int longueurMotSecret, char lettreEntree, char *lettreTapee);
int verificationVictoire(int longueurMotSecret, int *emplacementTrouve);
void afficherVictoire(SDL_Surface *ecran, char *motSecret, int longueur);
void afficherDefaite(SDL_Surface *ecran, char *motSecret, int longueur);
/********************************************************************
FONCTION main
int main(int argc, char *argv[])
{
//Déclaration des variables SDL
SDL_Surface *ecran = NULL; //Déclaration de la surface
//Jouer de la musique à l'accueil
FSOUND_STREAM *musique = NULL; //pointeur vers une musique (qui sera lu en streaming)
FSOUND_Init(44100,32,0) ; //Initialisation de FMOD (son)
musique = FSOUND_Stream_Open("musique.mp3", FSOUND_LOOP_NORMAL, 0, 0); //On met la musique en varialbe
FSOUND_Stream_SetLoopCount(musique, -1);
FSOUND_Stream_Play(FSOUND_FREE, musique); //On jour la musique en streaming
FSOUND_SetVolume(0, 80); //On baisse le volume pour le canal 0 (canal utilisé par la musique)
//Initialisation de la SDL
SDL_Init(SDL_INIT_VIDEO);
//On crée notre icone
SDL_WM_SetIcon(SDL_LoadBMP("icone.bmp"), NULL);
//Initialisation de la librairie TTF
TTF_Init();
//Initialisation de l'écran( écran de résolution 640*480...)
ecran = SDL_SetVideoMode(640,480,32,SDL_HWSURFACE | SDL_DOUBLEBUF);
//On donne un nom à notre fenetre
SDL_WM_SetCaption("'Pendons nous dans les bois' v1.0 by Haimet.S", NULL);
//On fait appele à la fonction qui accueil le choix que l'on fait
choixDeLAcceuil(ecran);
//Fermeture de TTF
TTF_Quit();
//Fermeture de la SDL
SDL_Quit();
//Fermeture de la musique de fond, et de FMOD
FSOUND_Stream_Close(musique);
FSOUND_Close() ;
return EXIT_SUCCESS;
/*Exit_success est une constante contenu dans stdlib qui annonce le
bon déroulement du programme */
}
/********************************************************************
FONCTION creerMotSecret
void creerMotSecret(char *mot) {
//Déclaration de nos variables locales
FILE *dictionnaire = NULL;
int i = 0, positionMot = 0;
//Ouverture du fichier en lecture seule
dictionnaire = fopen("dictionnaire.dat","r");
//On prend un nombre aléatoire savoir la position du mot du dictionnaire que l'on veut
//(nombre entre min_position et max_position)
srand(time(NULL)); //Initialisation
positionMot = (rand() % (MAX_POSITION - MIN_POSITION + 1)) + MIN_POSITION;
//On chosit le mot du dico qui est à la position "positionMot"
for(i = 0; i<positionMot; i++) {
fgets(mot,1000,dictionnaire);
}
//Fermeture du fichier
fclose(dictionnaire);
return; //Fonction "void" donc on ne retourne rien
}
/********************************************************************
FONCTION CHOIX DE L'ACCUEIL
void choixDeLAcceuil(SDL_Surface *ecran) {
//Variables locales
int continuer = 1;
int quitterJeu = 0;
//Création de nos surfaces
SDL_Surface *fondAccueil = NULL;
SDL_Rect positionFondAccueil; //Contient la positin du fond
//création de notre son
FSOUND_SAMPLE *cri = NULL ;
cri = FSOUND_Sample_Load(FSOUND_FREE, "cri.wav",0,0,0) ;
//On initialise nos surfaces (sauf l'écran qui est déjà initialisé) et leurs fonds
fondAccueil = SDL_LoadBMP("accueil.bmp");
positionFondAccueil.x = 0;
positionFondAccueil.y = 0;
//On colle le fond d'accueil sur l'écrand et on l'affiche (blit + flip) après avoir effacé l'écran
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format,0,0,0));
SDL_BlitSurface(fondAccueil,NULL,ecran,&positionFondAccueil);
SDL_Flip(ecran);
SDL_Event event; //On déclare une variable de type SDL_Event
//Tant que continuer vaut 1, on passe dans cette boucle
while (continuer) {
SDL_WaitEvent(&event); //Ici on attend un événement
switch(event.type) {
case SDL_QUIT : //Si l'événement est de type Quitter, on sors de la boucle en mettant continuer à 0
continuer = 0;
break;
case SDL_KEYDOWN : //Si l'événement est un clique sur une touche
switch(event.key.keysym.sym){ //Cette variable contient la touche sur laquelle on a cliqué
case SDLK_RETURN : //Si on a cliqué sur la touche ENTER, on joue le son et on peut jouer
FSOUND_PlaySound(FSOUND_FREE,cri) ;
quitterJeu = jouer(ecran);
//Si on nous renvoie 0, on quitte le programme
if(quitterJeu == 1) {
continuer = 0;
}
break;
default :
continuer = 1;
break;
} //fin du switch pour la récupération de la touche appuyée
}
}
//Fermeture des surfaces
SDL_FreeSurface(fondAccueil);
//Fermeture du son
FSOUND_Sample_Free(cri);
}
/********************************************************************
FONCTION JOUER
int jouer(SDL_Surface *ecran) {
//Variable locale
int coupFoireux = 0;
char motSecret[50] = "", lettreTapee[30] = "";
int longueurMotSecret = 0;
char lettreEntree = 0;
int gagne = 0, perdu = 0;
int emplacementTrouve[50];
int i = 0, trouve = 0;
//Création de sons
FSOUND_SAMPLE *erreur = NULL ;
FSOUND_SAMPLE *sonGagne = NULL ;
FSOUND_SAMPLE *sonPerdu = NULL ;
erreur = FSOUND_Sample_Load(FSOUND_FREE, "erreur.wav",0,0,0) ;
sonGagne = FSOUND_Sample_Load(FSOUND_FREE, "gagne.wav",0,0,0) ;
sonPerdu = FSOUND_Sample_Load(FSOUND_FREE, "perdu.wav",0,0,0) ;
//On initialise nos surfaces (sauf l'écran qui est déjà initialisé) et leurs positionnement
SDL_Surface *fondJeu = NULL;
SDL_Rect posFondJeu;
//On donne une image à fondJeu et une position
fondJeu = SDL_LoadBMP("fondJeu.bmp");
posFondJeu.x = 0;
posFondJeu.y = 0;
//On colle le fond d'accueil sur l'écrand et on l'affiche (blit + flip) après avoir effacé l'écran
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format,0,0,0));
SDL_BlitSurface(fondJeu,NULL,ecran,&posFondJeu);
SDL_Flip(ecran);
//appel de la fonction de création d'un mot, et récupération de la longueur du mot
creerMotSecret(motSecret);
longueurMotSecret = strlen(motSecret)-1; //On ne compte pas le \n de la chaine
//Mise à zéro du tableau contenant les emplacement des lettres trouvée
for(i = 0; i<50; i++) {
emplacementTrouve[i] == 0;
}
//Tant qu'on a pas gagné et qu'on a pas perdu, on fait le code suivant
while(gagne == 0 && perdu == 0) {
//Fonction affichant les emplacement vide du mot secret
afficherEcranJeu(ecran,fondJeu,longueurMotSecret, motSecret, coupFoireux, emplacementTrouve);
//On récupère une lettre entrée
lettreEntree = recupererLettre(erreur);
//Si on a taper sur quitter (et donc renvoyé 0) on renvoie 0
if(lettreEntree == 0) {
//Fermeture des sons
FSOUND_Sample_Free(erreur);
return(1);
}
else {
//On va voir si la lettre renvoyée est la bonne
trouve = verificationLettreEntree(motSecret,emplacementTrouve,longueurMotSecret, lettreEntree, lettreTapee);
}
//Si on a pas trouvé de lettre, on incrémente la variable coupFoireux
if (trouve == 0) {
coupFoireux ++;
//Si on a 8 coups foireux, on affiche le fin de jeu
if(coupFoireux == 8) {
perdu = 1;
break;
}
}
//Si on a trouve, on regarde si on a gagne
else if(trouve == 1) {
gagne = verificationVictoire(longueurMotSecret, emplacementTrouve);
}
else {
FSOUND_PlaySound(FSOUND_FREE,erreur);
}
}
if(gagne == 1) {
afficherVictoire(ecran, motSecret, longueurMotSecret);
FSOUND_PlaySound(FSOUND_FREE,sonGagne);
}
else if(perdu == 1) {
afficherDefaite(ecran, motSecret, longueurMotSecret);
FSOUND_PlaySound(FSOUND_FREE,sonPerdu);
}
//On arrete le temps pour que le son de victoire ou défaite ait le temps de se jouer
SDL_Delay(2000);
//Fermeture des sons
FSOUND_Sample_Free(erreur);
FSOUND_Sample_Free(sonGagne);
FSOUND_Sample_Free(sonPerdu);
return(0);
}
/********************************************************************
FONCTION RECUPERE LETTRE
char recupererLettre(FSOUND_SAMPLE *erreur) {
//Déclaration des variables locales
int continuer = 1;
SDL_Event event2;
while (continuer) {
SDL_WaitEvent(&event2);
switch(event2.type) {
//Si on quitte, on retourne 0 qui fait en sorte que le programme se termine en libérant toute la mémoire allouée
case SDL_QUIT:
return(0);
break;
case SDL_KEYDOWN :
/*On récupère la touche sur laquelle on a appuyé et on renvoie la lettre correspondante
Attention la SDL gère les claviers QWERTY, donc on fait en sorte de
travailler avec un clavier AZERTY*/
switch(event2.key.keysym.sym) {
case SDLK_q :
return('A');
break;
case SDLK_b :
return('B');
break;
case SDLK_c :
return('C');
break;
case SDLK_d :
return('D');
break;
case SDLK_e :
return('E');
break;
case SDLK_f :
return('F');
break;
case SDLK_g :
return('G');
break;
case SDLK_h :
return('H');
break;
case SDLK_i :
return('I');
break;
case SDLK_j :
return('J');
break;
case SDLK_k :
return('K');
break;
case SDLK_l :
return('L');
break;
case SDLK_SEMICOLON :
return('M');
break;
case SDLK_n :
return('N');
break;
case SDLK_o :
return('O');
break;
case SDLK_p :
return('P');
break;
case SDLK_a :
return('Q');
break;
case SDLK_r :
return('R');
break;
case SDLK_s :
return('S');
break;
case SDLK_t :
return('T');
break;
case SDLK_u :
return('U');
break;
case SDLK_v :
return('V');
break;
case SDLK_z :
return('W');
break;
case SDLK_x :
return('X');
break;
case SDLK_y :
return('Y');
break;
case SDLK_w :
return('Z');
break;
//Par défaut, on ne récupère rien mais on joue un son d'erreur
default :
FSOUND_PlaySound(FSOUND_FREE,erreur) ;
continuer = 1;
}
}
}
}
/********************************************************************
FONCTION AFFICHAGE EMPLACEMENT VIDE DU MOT SECRET
void afficherEcranJeu(SDL_Surface *ecran, SDL_Surface *fondJeu, int longueur, char *motSecret, int coupFoireux, int *emplacementTrouve) {
//Création de nos variable locales
SDL_Surface *texte = NULL, *pendu = NULL;
SDL_Color rouge = {255, 0, 0};
SDL_Rect position;
TTF_Font *police = NULL;
char motVide[50] = "";
int i = 0;
//Création de la police
police = TTF_OpenFont("bloody.ttf", 30);
//On défini le texte qu'on va afficher
for(i = 0; i<longueur; i++) {
if(emplacementTrouve[i] == 1) {
motVide[i] = motSecret[i];
}
else {
motVide[i] = '-';
}
}
//On donne une valeur à texte
texte = TTF_RenderText_Blended(police, motVide, rouge);
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
position.x = 0;
position.y = 0;
SDL_BlitSurface(fondJeu, NULL, ecran, &position); /* Blit du fond */
position.x = 400;
position.y = 280;
SDL_BlitSurface(texte, NULL, ecran, &position); /* Blit du texte par-dessus */
//Si on a un au moins un coup foireux, on affiche le pendu
if(coupFoireux>0) {
position.x = 0;
position.y = 0;
switch(coupFoireux) {
case 1 :
pendu = SDL_LoadBMP("1.bmp");
break;
case 2 :
pendu = SDL_LoadBMP("2.bmp");
break;
case 3 :
pendu = SDL_LoadBMP("3.bmp");
break;
case 4 :
pendu = SDL_LoadBMP("4.bmp");
break;
case 5 :
pendu = SDL_LoadBMP("5.bmp");
break;
case 6 :
pendu = SDL_LoadBMP("6.bmp");
break;
case 7 :
pendu = SDL_LoadBMP("7.bmp");
break;
}
SDL_BlitSurface(pendu, NULL, ecran, &position);
}
SDL_Flip(ecran);
//On ferme la police et la surface texte
TTF_CloseFont(police);
SDL_FreeSurface(texte);
}
/********************************************************************
FONCTION VERIFICATION LETTRE ENTREE
int verificationLettreEntree(char *motSecret,int *emplacementTrouve,int longueurMotSecret, char lettreEntree, char *lettreTapee) {
int i = 0, trouve = 0, dejaTapee = 0, longueur = 0;
//Calcul du nombre de lettre que l'on a dans lettreTape
longueur = strlen(lettreTapee);
//On passe le tableau de char en revue voir si on a déjà tapé la lettre entree
for(i = 0; i<longueur; i++) {
//Si on a déjà la lettre, on donne la valeur 1 à dejaTapee
if(lettreTapee[i] == lettreEntree) {
dejaTapee = 1;
}
}
//Si la lettre n'est pas encore tapée :
if(dejaTapee == 0) {
//On enregistre la lettre tapee
lettreTapee[i] = lettreEntree;
//On regarde une par un les lettres du mot secret
for(i = 0; i<longueurMotSecret; i++) {
//Si la lettre entree a été trouvé à la lettre 2 par exemple, on note 1 dans
// le tableau d'emplacement trouvé à l'indice 2
if(lettreEntree == motSecret[i]) {
emplacementTrouve[i] = 1;
trouve = 1;
}
}
return(trouve);
}
//Si la lettre est déjà tapée, on renvoie 2
else {
return(2);
}
}
/********************************************************************
FONCTION VERIFICATION VICTOIRE
int verificationVictoire(int longueurMotSecret, int *emplacementTrouve) {
int victoire = 1, i = 0;
for(i = 0; i<longueurMotSecret; i++) {
//Si un des éléments du tableau vaut 0, on renvoie victoire = 0
if(emplacementTrouve[i] != 1) {
victoire = 0;
}
}
return(victoire);
}
/********************************************************************
FONCTION AFFICHAGE VICTOIRE
void afficherVictoire(SDL_Surface *ecran, char *motSecret, int longueur) {
//Déclaration des variables
SDL_Surface *fondVictoire = NULL, *texteVictoire = NULL, *dessin = NULL;
SDL_Rect position;
TTF_Font *police = NULL;
int i = 0;
char mot[50] = "";
SDL_Color rouge = {255, 0, 0};
//On reforme le mot secret, car on à \n à la fin
for(i = 0; i<longueur; i++) {
mot[i] = motSecret[i];
}
police = TTF_OpenFont("bloody.ttf", 30); //création de la police
texteVictoire = TTF_RenderText_Blended(police, mot, rouge); //Création du texte
//Affichage
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0)); //On efface l'écran
fondVictoire = SDL_LoadBMP("gagne.bmp");
position.x = 0;
position.y = 0;
SDL_BlitSurface(fondVictoire,NULL,ecran,&position);
dessin = SDL_LoadBMP("pasPendu.bmp");
position.x = 0;
position.y = 0;
SDL_BlitSurface(dessin, NULL, ecran, &position);
position.x = 400;
position.y = 280;
SDL_BlitSurface(texteVictoire,NULL,ecran,&position);
SDL_Flip(ecran);
//On libère la mémoire
SDL_FreeSurface(fondVictoire);
SDL_FreeSurface(texteVictoire);
SDL_FreeSurface(dessin);
TTF_CloseFont(police);
return;
}
/********************************************************************
FONCTION AFFICHAGE DEFAITE
void afficherDefaite(SDL_Surface *ecran, char *motSecret, int longueur) {
//Déclaration des variables
SDL_Surface *fondDefaite = NULL, *texteDefaite = NULL, *pendu = NULL;
SDL_Rect position;
TTF_Font *police = NULL;
int i = 0;
char mot[50] = "";
SDL_Color rouge = {255, 0, 0};
//On reforme le mot secret, car on à \n à la fin
for(i = 0; i<longueur; i++) {
mot[i] = motSecret[i];
}
police = TTF_OpenFont("bloody.ttf", 30); //création de la police
texteDefaite = TTF_RenderText_Blended(police, mot, rouge); //Création du texte
//Affichage
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0)); //On efface l'écran
fondDefaite = SDL_LoadBMP("perdu.bmp");
position.x = 0;
position.y = 0;
SDL_BlitSurface(fondDefaite,NULL,ecran,&position);
pendu = SDL_LoadBMP("8.bmp");
position.x = 0;
position.y = 0;
SDL_BlitSurface(pendu,NULL,ecran,&position);
position.x = 400;
position.y = 280;
SDL_BlitSurface(texteDefaite,NULL,ecran,&position);
SDL_Flip(ecran);
//On libère la mémoire
SDL_FreeSurface(fondDefaite);
SDL_FreeSurface(texteDefaite);
SDL_FreeSurface(pendu);
TTF_CloseFont(police);
return;
}
Conclusion :
Enjoy
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.