
|
| | | [C][SDL]Demander une chaîne de caractère à l'utilisateur | |
| | Auteur | Message |
|---|
Rayman3640 Experimenté


Nombre de messages: 429 Age: 15 Programme utilisé (Gm/RmXp/...): GM7 Pro/gcc/Vim/RM2003/ Etudes: Collégien Loisirs: Informatique, tennis, lecture, écriture, jeux vidéo, handball Date d'inscription: 29/04/2008
 | Sujet: [C][SDL]Demander une chaîne de caractère à l'utilisateur Sam 30 Mai - 13:41 | |
| Bonjour, Dans le cadre de mon projet (voir signature), j'ai dû créer un système permettant de simuler une zone de texte avec la SDL. Comme je l'ai fini, je vous le propose ici, afin que vous puissiez l'utiliser dans vos projets. Je suis ouvert à tout commentaire ! PrérequisAvoir installé la SDL, SDL_Image et SDL_TTF. InstallationAjoutez ces deux fichiers à votre projet : | Code: | /* zonetexte.c Par Rayman3640 Rôle : permettre au créateur de simuler des zones de texte avec la SDL */
#include <stdlib.h> #include <stdio.h> #include <SDL/SDL.h> #include <SDL/SDL_ttf.h> #include <SDL/SDL_image.h> #include "zonetexte.h"
void lireDonneeZoneTexte(SDL_Surface *surface, TTF_Font *police, char *chaineEntree, char *introductionInitiale, char *texteDePreremplissage, long nombreDeCaracteresMaximal) { int continuer = 1, majuscule = 0; char introduction[100] = "", chaineFinale[100] = ""; SDL_Surface *texte, *barre = NULL; SDL_Color noir = {0,0,0}; SDL_Rect positionTexte; long positionCaractere = 0; SDL_Event event; barre = IMG_Load("Curseur.png"); detecterErreurs(surface,barre,police,chaineEntree,texteDePreremplissage,nombreDeCaracteresMaximal); strcpy(introduction,introductionInitiale); strcpy(chaineEntree,texteDePreremplissage); positionCaractere = strlen(chaineEntree); SDL_FillRect(surface,NULL,SDL_MapRGB(surface->format,255,255,255)); SDL_EnableKeyRepeat(100,100); SDL_Flip(surface); while(continuer) { SDL_WaitEvent(&event); switch(event.type) { case SDL_QUIT: continuer = 0; break; case SDL_KEYDOWN: lireCaractereZoneTexte(event,&majuscule,chaineEntree,&positionCaractere,&continuer,nombreDeCaracteresMaximal); strcat(introduction,chaineEntree); strcpy(chaineFinale,introduction); strcpy(introduction,introductionInitiale); break; } if(strlen(chaineFinale) <= 0) { strcat(introduction,chaineEntree); strcpy(chaineFinale,introduction); strcpy(introduction,introductionInitiale); } texte = TTF_RenderUTF8_Solid(police,chaineFinale,noir); positionTexte.x = 0; positionTexte.y = 0; SDL_BlitSurface(texte,NULL,surface,&positionTexte); blitterCurseur(chaineFinale,&positionTexte,police,introduction,chaineEntree,surface,barre, positionCaractere); SDL_Flip(surface); SDL_FillRect(surface,NULL,SDL_MapRGB(surface->format,255,255,255)); } SDL_FreeSurface(texte); SDL_FreeSurface(barre);
}
void detecterErreurs(SDL_Surface *surface, SDL_Surface *barre, TTF_Font *police, char *chaineEntree, char *texteDePreremplissage, long nombreDeCaracteresMaximal) { if(surface == NULL) { fprintf(stderr,"Le pointeur sur surface vaut NULL, donc le texte ne peut pas être affiché à l'écran.\n"); exit(EXIT_FAILURE); } if(barre == NULL) { fprintf(stderr,"Erreur lors de l'ouverture de l'image Curseur.png: %s\n",SDL_GetError()); exit(EXIT_FAILURE); } if(police == NULL) { fprintf(stderr,"Le pointeur sur police vaut NULL, donc aucune police ne peut être ouverte.\n"); exit(EXIT_FAILURE); } if(chaineEntree == NULL) { fprintf(stderr,"La chaîne entrée vaut NULL, donc l'utilisateur ne peut rentrer aucune chaîne.\n"); exit(EXIT_FAILURE); } if(nombreDeCaracteresMaximal < 1) { fprintf(stderr,"La taille maximale est nulle, donc l'utilisateur ne peut entrer aucune chaîne.\n"); exit(EXIT_FAILURE); } if(texteDePreremplissage != NULL && strlen(texteDePreremplissage) > nombreDeCaracteresMaximal) { fprintf(stderr,"Le nombre de caractères du texte de préremplissage est supérieur au nombre de caractères maximal.\n"); exit(EXIT_FAILURE); }
}
void blitterCurseur(char *chaineFinale, SDL_Rect *positionTexte, TTF_Font *police, char *introduction, char *chaineEntree, SDL_Surface *surface, SDL_Surface *barre, long positionCaractere) { int longueurSurfaceTexte = 0, longueurSurfaceTexte2 = 0, longueurSurfaceTexte3 = 0, largeurSurfaceTexte = 0; SDL_Rect positionBarre; if(strlen(chaineFinale) > 0) { positionBarre.x = positionTexte->x; if(TTF_SizeUTF8(police,introduction,&longueurSurfaceTexte,&largeurSurfaceTexte) == 0) { positionBarre.x += longueurSurfaceTexte; longueurSurfaceTexte = 0; } if(TTF_SizeUTF8(police,chaineEntree,&longueurSurfaceTexte2,&largeurSurfaceTexte) == 0) { if(TTF_SizeUTF8(police,&chaineEntree[positionCaractere],&longueurSurfaceTexte3,&largeurSurfaceTexte) == 0) { longueurSurfaceTexte = longueurSurfaceTexte2 - longueurSurfaceTexte3; } positionBarre.x += longueurSurfaceTexte; } positionBarre.y = positionTexte->y; SDL_BlitSurface(barre,NULL,surface,&positionBarre); }
}
void lireCaractereZoneTexte(SDL_Event event, int *majuscule, char *chaine, long *positionCaractere, int *continuer, long nombreDeCaracteresMaximal) { char caractereEntre = 0; int lettreEntree = 0, diminuerPositionCaractere = 1; long i = 0; if(event.key.keysym.mod & KMOD_SHIFT) { *majuscule = 1; } else { *majuscule = 0; } switch(event.key.keysym.sym) { case SDLK_LEFT: if(*positionCaractere > 0) *positionCaractere -= 1; break; case SDLK_RIGHT: if(*positionCaractere < strlen(chaine)) *positionCaractere += 1; break; case SDLK_BACKSPACE: if(*positionCaractere > 0) { for(i = *positionCaractere - 1; i < strlen(chaine); i++) { if(i > -1) chaine[i] = chaine[i+1]; else diminuerPositionCaractere = 0; } if(diminuerPositionCaractere) *positionCaractere -= 1; else *positionCaractere = 1; } break; case SDLK_ESCAPE: *continuer = 0; break; case SDLK_RETURN: *continuer = 0; break; default: break; } detecterLettre(event,&lettreEntree,&caractereEntre,majuscule); if(lettreEntree == 1 && strlen(chaine) <= nombreDeCaracteresMaximal) { insererCaractereDansChaine(*positionCaractere,chaine,caractereEntre); *positionCaractere += 1; } }
void detecterLettre(SDL_Event event, int *lettreEntree, char *caractereEntre, int *majuscule) { long i = 0; for(i = 0; i < 26; i++) //Lettres sans accents minuscules et majuscules { if(event.key.keysym.sym == SDLK_a + i) { entrerLettre(lettreEntree,65 + i,caractereEntre); if(!(*majuscule)) { *caractereEntre += 32; } break; } } for(i = 0; i < 27; i++) { if(event.key.keysym.sym == SDLK_AMPERSAND + i) { entrerLettre(lettreEntree,38 + i,caractereEntre); } } for(i = 0; i < 5; i++) { if(event.key.keysym.sym == SDLK_SPACE + i) { entrerLettre(lettreEntree,32 + i,caractereEntre); } } switch(event.key.keysym.sym) //Caractères spéciaux { case SDLK_BACKSLASH: entrerLettre(lettreEntree,92,caractereEntre); break; default: break; } for(i = 0; i < 10; i++) { if(event.key.keysym.sym == SDLK_KP0 + i) //Nombres du pavé numérique { entrerLettre(lettreEntree,48 + i,caractereEntre); } }
}
void entrerLettre(int *lettreEntree, long numeroCaractere, char *caractere) { if(!(*lettreEntree)) { *lettreEntree = 1; *caractere = numeroCaractere; } }
void insererCaractereDansChaine(long positionCaractere, char *chaine, char caractereAInserer) { char chaine2[100] = ""; strcpy(chaine2,&chaine[positionCaractere]); chaine[positionCaractere] = caractereAInserer; strcpy(&chaine[positionCaractere+1],chaine2); } |
| Code: | /* zonetexte.h Par Rayman3640 Rôle : définir les fonctions utilisées par le fichier de lecture de chaînes au clavier */
#ifndef DEF_ZONETEXTE #define DEF_ZONETEXTE #include <SDL/SDL.h> void lireDonneeZoneTexte(SDL_Surface *surface, TTF_Font *police, char *chaineEntree, char *introductionInitiale, char *texteDePreremplissage, long nombreDeCaracteresMaximal); void detecterErreurs(SDL_Surface *surface, SDL_Surface *barre, TTF_Font *police, char *chaineEntree, char *texteDePreremplissage, long nombreDeCaracteresMaximal); void lireCaractereZoneTexte(SDL_Event event, int *majuscule, char *chaine, long *positionCaractere, int *continuer, long nombreDeCaracteresMaximal); void entrerLettre(int *lettreEntree, long numeroCaractere, char *caractere); void insererCaractereDansChaine(long positionCaractere, char *chaine, char caractereAInserer); void blitterCurseur(char *chaineFinale, SDL_Rect *positionTexte, TTF_Font *police, char *introduction, char *chaineEntree, SDL_Surface *surface, SDL_Surface *barre, long positionCaractere); void detecterLettre(SDL_Event event, int *lettreEntree, char *caractereEntre, int *majuscule);
#endif
|
Ensuite, dans le même dossier que vos sources, ajoutez cette image, que vous nommerez Curseur.png : 
Utilisation Pour récupérer une chaîne de caractères, utilisez la fonction lireDonneeZoneTexte, qui fonctionne comme ceci :
| Code: | void lireDonneeZoneTexte(SDL_Surface *surface, TTF_Font *police, char *chaineEntree, char *introductionInitiale, char *texteDePreremplissage, long nombreDeCaracteresMaximal);
|
- SDL_Surface *surface est le pointeur sur la surface où le texte doit être écrit
- TTF_Font *police est la police à utiliser
- char *chaineEntree est la chaîne qui contiendra ce qu'à entré l'utilisateur
- char *introductionInitiale est le texte affiché avant la zone de texte (par exemple "NOM: " ou encore "Adresse: "),
- char *texteDePreremplissage est le texte mis par défaut dans la zone de texte
- long nombreDeCaracteresMaximal est le nombre maximal de caractères que l'utilisateur peut taper (attention, le caractère /0 ne doit pas être inclus dans le nombre)
N'oubliez pas d'inclure zonetexte.h !
| Code: | #include "zonetexte.h"
|
Exemple
| Code: | #include <stdio.h> #include <stdlib.h> #include <string.h> #include <SDL/SDL.h> #include <SDL/SDL_ttf.h> #include <SDL/SDL_image.h> #include "zonetexte.h"
int main(int argc, char *argv[]) { SDL_Surface *ecran = NULL; int continuer = 1; char chaine[100] = ""; TTF_Font *police = NULL; if(SDL_Init(SDL_INIT_VIDEO) == -1) { fprintf(stderr,"Erreur lors de l'initialisation de la SDL : %s\n",SDL_GetError()); exit(EXIT_FAILURE); } if(TTF_Init() == -1) { fprintf(stderr,"Erreur lors de l'initialisation de SDL_TTF : %s\n",TTF_GetError()); exit(EXIT_FAILURE); } police = TTF_OpenFont("RostockKaligraph.ttf",40); if(police == NULL) { fprintf(stderr,"Erreur police : %s",TTF_GetError()); exit(EXIT_FAILURE); } ecran = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE); SDL_WM_SetCaption("Demander une chaîne de caractères à l'utilisateur", NULL); SDL_FillRect(ecran,NULL,SDL_MapRGB(ecran->format,255,255,255)); SDL_Flip(ecran); while (continuer) { lireDonneeZoneTexte(ecran,police,chaine,"Mon site préféré : ","Le Site du Zer0",99); continuer = 0; } TTF_CloseFont(police); TTF_Quit(); SDL_Quit(); return EXIT_SUCCESS; }
|
Remarques
- J'espère que l'implémentation se fera sans problème, car je n'ai pas essayé mon système séparément de mon projet.
- Pour faire une lettre majuscule, je n'ai pas réussi à utiliser le KMOD_CAPS, il faut donc faire Shift + Lettre à mettre en majuscule.
- Je n'ai pas mis une grande variété de caractères (c'est long et chiant à faire ! :p ) : seulement les lettres (sans accents), les chiffres et quelques autres caractères. Mais si vous le désirez, vous pouvez modifier la fonction detecterLettre pour cela.

_________________ Supra-Quest, un jeu vidéo concentrant une aventure épique, un monde presque sans limites à découvrir et un système de combat novateur ! N'oubliez pas de visiter le SQ-Devblog, le blog de développement du jeu ! |
|  | | Xierra54 Admin - .: el traductor :.


Nombre de messages: 8504 Age: 50 Programme utilisé (Gm/RmXp/...): GM (6.1 et 7 enregistrées), Purebasic (démo) Etudes: Supérieures Loisirs: ordinateur Date d'inscription: 13/08/2005
 | Sujet: Re: [C][SDL]Demander une chaîne de caractère à l'utilisateur Dim 31 Mai - 13:10 | |
| En tout cas, bravo Rayman3640 pour ta réalisation et tes connaissances en C. A+ |
|  | | Rayman3640 Experimenté


Nombre de messages: 429 Age: 15 Programme utilisé (Gm/RmXp/...): GM7 Pro/gcc/Vim/RM2003/ Etudes: Collégien Loisirs: Informatique, tennis, lecture, écriture, jeux vidéo, handball Date d'inscription: 29/04/2008
 | Sujet: Re: [C][SDL]Demander une chaîne de caractère à l'utilisateur Dim 31 Mai - 13:25 | |
| Merci !  J'ai pris du temps à apprendre ce langage, mais maintenant, je peux faire ce que je veux avec.  _________________ Supra-Quest, un jeu vidéo concentrant une aventure épique, un monde presque sans limites à découvrir et un système de combat novateur ! N'oubliez pas de visiter le SQ-Devblog, le blog de développement du jeu ! |
|  | | Fireranger Possedé par Mark Overmars


Nombre de messages: 1360 Age: 16 Programme utilisé (Gm/RmXp/...): Game Maker 7 PRO, Visual Basic 9.0, Visual C++ et Code::Blocks Date d'inscription: 22/11/2007
 | Sujet: Re: [C][SDL]Demander une chaîne de caractère à l'utilisateur Lun 1 Juin - 22:50 | |
| C'est très bien. Maintenat, prochaine étape, le faire sans la librairie SDL_TTF  Tu peux aussi ajouter un paramètre pour la couleur, la taille de la police, etc. à moins que ça ne fasse partie de la police déjà  Bonne continuation ! |
|  | | kimerafusion Possedé par Mark Overmars


Nombre de messages: 1622 Programme utilisé (Gm/RmXp/...): gamemaker 7.0 pro, code::blocks, adobe dreamweaver, gnu-gcc Etudes: futur ingénieur logiciel (j'aimerais bien bosser sur de la nanotechnologie, biotechnologie ou autres), seconde GT Loisirs: jeux-vidéos - programmation (C/C++, Qt, SDL) Date d'inscription: 14/10/2008
 | |  | | Rayman3640 Experimenté


Nombre de messages: 429 Age: 15 Programme utilisé (Gm/RmXp/...): GM7 Pro/gcc/Vim/RM2003/ Etudes: Collégien Loisirs: Informatique, tennis, lecture, écriture, jeux vidéo, handball Date d'inscription: 29/04/2008
 | Sujet: Re: [C][SDL]Demander une chaîne de caractère à l'utilisateur Mar 2 Juin - 21:17 | |
| | Fireranger a écrit: | C'est très bien. Maintenat, prochaine étape, le faire sans la librairie SDL_TTF Tu peux aussi ajouter un paramètre pour la couleur, la taille de la police, etc. à moins que ça ne fasse partie de la police déjà 
Bonne continuation ! | Merci !  Et oui, l'utilisateur (enfin, le programmeur) peut paramétrer la police pour changer la taille et la couleur.
| kimerafusion a écrit: | La SDL, c'est vraiment bien trop compliqué pour moi... il me faudrait un prof plutôt qu'une page à lire  | Moyennant 10€ / minute, je peux t'aider. 
Je posterai bientôt mon éditeur de niveaux pour RPG fait avec la SDL sur le forum. Peut-être dans une semaine (ou deux)..._________________ Supra-Quest, un jeu vidéo concentrant une aventure épique, un monde presque sans limites à découvrir et un système de combat novateur ! N'oubliez pas de visiter le SQ-Devblog, le blog de développement du jeu ! |
|  | | kimerafusion Possedé par Mark Overmars


Nombre de messages: 1622 Programme utilisé (Gm/RmXp/...): gamemaker 7.0 pro, code::blocks, adobe dreamweaver, gnu-gcc Etudes: futur ingénieur logiciel (j'aimerais bien bosser sur de la nanotechnologie, biotechnologie ou autres), seconde GT Loisirs: jeux-vidéos - programmation (C/C++, Qt, SDL) Date d'inscription: 14/10/2008
 | Sujet: Re: [C][SDL]Demander une chaîne de caractère à l'utilisateur Mer 3 Juin - 13:52 | |
| waow stylé t'es vraiment trop fort combien d'heures ça t'a prit de faire un éditeur de RPG? |
|  | | Rayman3640 Experimenté


Nombre de messages: 429 Age: 15 Programme utilisé (Gm/RmXp/...): GM7 Pro/gcc/Vim/RM2003/ Etudes: Collégien Loisirs: Informatique, tennis, lecture, écriture, jeux vidéo, handball Date d'inscription: 29/04/2008
 | Sujet: Re: [C][SDL]Demander une chaîne de caractère à l'utilisateur Mer 3 Juin - 13:57 | |
| Pas tant que ça. Enfin ça dépend si tu comptes le temps que j'ai pris pour faire ce système de zone de texte, car la gestion des chaînes de caractères en C est assez corsée... J'ai dû fouiller dans la doc de SDL TTF, faire un système de curseur, etc. Pour le moment je suis (assez) loin d'avoir fini l'éditeur mais je pense que j'y aurai passé 7-10h (peut-être que je me trompe complètement). _________________ Supra-Quest, un jeu vidéo concentrant une aventure épique, un monde presque sans limites à découvrir et un système de combat novateur ! N'oubliez pas de visiter le SQ-Devblog, le blog de développement du jeu ! |
|  | | | | [C][SDL]Demander une chaîne de caractère à l'utilisateur | |
|
| Page 1 sur 1 |
| | Permission de ce forum: | Vous pouvez répondre aux sujets dans ce forum
| |
| |
| |
|