Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Programmation > C > [SDL] Faire des animations avec SDLP_Anim > Lecture du tutoriel

[SDL] Faire des animations avec SDLP_Anim

Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Avatar
Auteur : popop9900
Note : Pas de note

Plus d'informations Plus d'informations
Bienvenue dans mon tutorial !
Ce dernier a pour but de vous apprendre à gérer des animations simplement grâce à un outil dont je suis l'auteur : SDLP_Anim.
Les utilisateurs de Dev-C++ auront une petite surprise dans ce tutorial (Ils ont quand même de la chance ceux-là ^^ ) !
Les autres, eh ben tant pis pour vous na ! :D
Pour utiliser cet outil, vous aurez besoin d'avoir lu tout le tutorial de M@théo21 sur le C/C++ (n'oubliez pas la SDL).
Sommaire du chapitre :
Icône du chapitre

1) Téléchargement

Bien, la 1ère chose est de télécharger notre fichier ZIP qui contient notre header pour que nos fonctions fonctionnent :p
C'est ici : SDLP_Anim.zip !
Version Actuelle de SDLP_Anim.h : 1.10
Il se peut qu'une nouvelle version sorte et que ne vous le remarquiez pas. Dans ce cas, de nouvelles fonctions ajoutées dans ce tutorial ne fonctionneront pas ! Il faut remplacer l'ancien fichier par le nouveau qui est en téléchargement à coter de SDLP_Anim.zip.

~ Windows ~



Code::Blocks



Ouvrez le fichier compressé que vous avez téléchargé.
Il contient un header, deux fichiers texte et 3 images.
Si vous aimez l'anglais, lisez LICENSE.txt ( Y'a plus personne tout à coup ^^ )
Utilisation.txt est un petit paragraphe concernant les virus.
Et le meilleur pour la fin, SDLP_Anim.h !

Ah, j'oubliais, les images, mettez ces fichiers dans un coin pour le moment.
Pourquoi ? o_O

Vous êtes du genre curieux vous dis donc ! On les utilisera dans un futur proche...
Et arrêter de me regarder comme ça, vous me faites peur :lol:

Un peu de sérieux dans la salle :magicien:
Vous allez placer ce fichier à l'aide du chemin suivant :
C:\Program Files\CodeBlocks\mingw32\include\SDL\SDLP_Anim.h

Dev-C++



La manipulation d'installation avec Dev-C++ est la même que celle de Code::Block.
Chemin du fichier: C:\Program Files\Dev-C++\mingw32\include\SDL\SDLP_Anim.h

J'ai 'fabriqué' 2/3 fichiers dans mon compilateur (Dev-C++) qui est en quelque sorte un raccourci quand vous créez un nouveau projet.
Le fichier ZIP est disponible ici !
Vous décompressez le fichier et insérez le tout dans le dossier Templates.
Pour actionner le bouton, cliquez sur le bouton 'Nouveau projet' puis vous aurez le choix entre plusieurs type de programme comme la console. Cherchez Projet SDL puis cliquer dessus. Un code en SDL typique vient d'apparaître et ce n'est pas tout, vous deviez avant mettre dans l'éditeur de lien -lmingw32, -lSDL ect... Et bien là, j'ai une bonne nouvelle pour vous, c'est déjà fait !
NOTE: L'éditeur de lien contient ces fichiers: -lmingw32 -lSDLmain -lSDL -lSDL_image -lFMOD -lSDL_ttf ../../mingw32/lib/sdlgfx.lib
Il se peut que vous n'ayez pas déjà tout installé, retirez les fichiers que vous n'avez pas installés. Disponible que sur Dev-C++ !

Après l'installation de l'astuce, voilà ce que ça pourrait donner :Image utilisateur

Bon certes, il n'y a pas d'icône mais c'est très pratique car on n'a pas besoin d'inclure à la main -lmingw32 -lSDLmain (Que le monde est bien fait :) )

Visual C++ 2005 Express



Il n'y a pas grand chose qui change à par que nous n'utilisons plus mingw32 mais VC. Mettez le header dans: C:\Program Files\Microsoft Visual Studio 8\VC\include\SDL\SDLP_Anim.h

Je ne connais pas bien cet IDE. Si un problème parvint sur un bon nombre de zéros, merci de me contacter par MP


En Général



Vous aurez ceci après vos manipulations (J'ai utilisé Code::Blocks) mais ça devrait être presque pareil pour les autres) :
Image utilisateur
Image tirée du tutorial de M@théo21 sur la SDL (modifiée)


~ Mac OS (Xcode) & Linux ~



Je ne sais pas comment vous aidez si vous êtes dans ce cas. :(


2) Animation Normal

Nous allons maintenant commencer la vraie partie du tutorial !
Je vous demande de creer un nouveau projet et de le compléter pendant tout le long du chapitre. Normalement, votre fichier .c est vide en ce moment.
Accrochez-vous, sa va secouer !

Les fonctions, nous en raffolons !




Prenons un code SDL de base (ayant installé SDL_image). Recopiez-le sur votre fichier .c.

Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
 
int main(int argc, char *argv[])
{
    SDL_Surface *ecran = NULL;
    SDL_Event event;
    int continuer = 1;
 
    SDL_Init(SDL_INIT_VIDEO);
 
    ecran = SDL_SetVideoMode(200, 200, 32, SDL_HWSURFACE);
    SDL_WM_SetCaption("Animations en SDL !", NULL);
    
    while (continuer)
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                continuer = 0;
            break;
        }
    
    SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));    
 
 
    SDL_Flip(ecran);
    }
    
    SDL_Quit();
 
    return EXIT_SUCCESS;
}

On va partir de ce code pour que vous n'oubliez rien. Complétez votre fichier .c à l'aide de toutes les fonctions présentes.

Code : C
1
ecran = SDL_SetVideoMode(200, 200, 32, SDL_HWSURFACE);

Bon, vous avez tous remarquez que si, avec ce code, on blitte une image, elle va scintiller (si vous doutez, essayer :p ) !
On va régler tout ça en mettant le double buffering :)

Code : C
1
ecran = SDL_SetVideoMode(200, 200, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);

Code : C
1
SDL_WaitEvent(&event);

Nous allons mettre SDL_PollEvent car une animation n'a pas besoin d'événement pour qu'elle se mette à fonctionner !

Code : C
1
SDL_PollEvent(&event);

Nous avons oublier quelque chose non ?
Heu... Tu aurais pas oublié l'header par hasard ? :-°

Ah voilà ce qui manquait !
Dans l'exemple du tutorial, on trouve ceci dans l'en-tête du fichier .c.

Code : C
1
2
3
4
5
#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDLP_Anim.h>

Vous allez devoir retenir à présent UNE seule structure.
Voici un exemple de son utilisation.

Code : C
1
SDLP_Anim Anim;

Tu n'as pas mis 'Anim' en pointeur, c'est fait exprès ?
Oui car j'ai trouvé beaucoup de bugs avec la déclaration de la structure en pointeur. J'ai fait donc en variable normal.

Bon, on a créé notre surface 'Anim'. Ça serait bien de libérer sa mémoire à celle là non ?
Pour cela, on va utilisé SDLP_FreeAnim !

Code : C
1
SDLP_FreeAnim(&Anim);
Et le tour est joué ! ;)

Maintenant, nous allons Charger l'animation. Reprenez les images qui étaient dans le dossier compressé. nous allons utiliser maintenant Feu.bmp
Je vais vous présenter le prototype de la fonction de chargement d'animation.

Mettez l'image dans le dossier de l'éxécutable. Sinon, l'image ne pourra pas être chargée avec l'exemple qui va suivre.


Code : C
1
int SDLP_LoadAnim(SDLP_Anim *str, char *SurfaceAnim, int nbPicture2, long temps, int coter1, int Loop1, int Util1);

Vous allez donc ici définir toutes les options de l'animation.

Nous verrons comment utiliser l'animation par évenement dans le chapitre 'Animation par Evenement'.


Code : C
1
SDLP_LoadAnim(&Anim, "Feu.bmp", 4, 1000, SDLP_DROITE, SDLP_INFINI, SDLP_NORMAL);

Ça va ? Vous suivez ? N'hésiter pas à relire si cela s'avère nécessaire !
Ça devient intéressant je trouve, pas vous ? :p

Maintenant, il faut définir la position de l'animation sur la fenêtre.
Or j'ai découvert qu'il était plus facile et plus compréhensible que vous délariez vous-même votre variable de type SDL_Rect ! Faites comme moi, donnez le nom de votre variable : 'pAnim' !

Code : C
1
2
3
4
SDL_Rect pAnim;
/* Chargement de l'animation. */
pAnim.x=0;
pAnim.y=0;

Bon, nous avons chargée notre animation. Mais c'est que dans la 'tête' de l'ordinateur ça ! Nous, on veut que ça s'affiche non ? NON ? :lol:
Nous allons utiliser la fonction de blittage la plus simple qui est jamais existé :D
Le prototype l'est aussi :

Code : C
1
void SDLP_BlitAnim(SDLP_Anim *str, SDL_Surface *ecran, SDL_Rect pos);


Et c'est tout ! :p

J'ai fait aussi une petite fonction pour la transparence:

Code : C
1
void SDLP_SetColorKeyAnim(SDLP_Anim *str, int R, int V, int B);



Voilà ! Nous avons nos fonctions maintenant. ;)
C'est déjà fini ?

Et Oui ! Je vous l'avez bien dit que ça serait simple ^^

Exercice



Maintenant, au boulot, je vous demande, à partir de Feu.bmp, me faire un joli feu tricolore qui 'bouge' toutes les secondes, de sens DROITE et que l'animation soit infini !
Je vous demande que le feu tricolore soit au centre de la fenêtre. Attention, je vous rappelle que Anim.Surface->w est égale à l'image du feu tricolore non-séparé !
Allez. 3.. 2.. 1.. Top Chrono c'est parti ! :D

Correction



Secret (cliquez pour afficher)


Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDLP_Anim.h>
 
/*                          SDLP_ANIM.C                                      
                          Créé par POPOP99O0       
                               Site du Zér0                                               
*/
 

int main(int argc, char *argv[])
{
    SDL_Surface *ecran = NULL;
    SDL_Rect pAnim;
    SDLP_Anim Anim;
    SDL_Event event;
    int continuer = 1;
 
    SDL_Init(SDL_INIT_VIDEO);
 
    ecran = SDL_SetVideoMode(200, 200, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
    SDL_WM_SetCaption("Animations en SDL !", NULL);
    
    SDLP_LoadAnim(&Anim, "Feu.bmp", 4, 1000, SDLP_DROITE, SDLP_INFINI, SDLP_NORMAL);
    
    pAnim.x=ecran->w / 2 - (Anim.Surface->w/4) / 2;
    pAnim.y=ecran->h / 2 - Anim.Surface->h / 2;;
    
    while (continuer)
    {
        SDL_PollEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                continuer = 0;
            break;
        }
    
    SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));    
    
    SDLP_BlitAnim(&Anim, ecran, pAnim);
    
    SDL_Flip(ecran);
    }
    SDLP_FreeAnim(&Anim);
    
    SDL_Quit();
 
    return EXIT_SUCCESS;
}





Ce chapitre ce termine ! Nous avons vu une animation automatique en quelque sorte. Dans le prochain chapitre, Il faudra faire un événement pour faire fonctionner l'animation !

3) Animation par Evènement

Faisons courir la chaton !



Nous allons utiliser 2 images qui restaient de SDLP_Anim.zip:
Image utilisateur

Et

Image utilisateur


On va animer ce chat quand on cliquera sur une touche.
C'est à dire que, quand on cliquera sur une touche, l'image qui va subir un évènement s'animera. Je prends l'exemple de zozor qui se déplace dans le tutorial sur les événements de M@théo21. Il est static quand il se déplace, l'image pourrait bouger et cela donnerai de la "vie" à l'image.
C'est ce que j'appelle une Animation par Evènement.

Nous allons découvrir une nouvelle fonction très bientôt.
Commençons d'abord par gérer cette animation normalement (c'est à dire, que l'ordinateur défilera lui-même).
Le code serait celui-ci :

Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDLP_Anim.h>
 
#define CATD      0
#define CATG      1
// Déclaration de defines

int main(int argc, char *argv[])
{
    SDL_Surface *ecran = NULL;
    SDLP_Anim Cat[2]; // variables de la structure SDLP_Anim
    SDL_Rect pCat;
    SDL_Event event;
    int continuer = 1;
    
    SDL_Init(SDL_INIT_VIDEO); 
    
    ecran = SDL_SetVideoMode(400, 400, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); 
    SDL_WM_SetCaption("SDLP_Anim - Evenement", NULL);
    
    SDLP_LoadAnim(&Cat[CATD], "CatD.png", 4, 200, SDLP_GAUCHE, SDLP_INFINI, SDLP_NORMAL); // On charge Anim.
    SDLP_LoadAnim(&Cat[CATG], "CatG.png", 4, 200, SDLP_GAUCHE, SDLP_INFINI, SDLP_NORMAL);
    
    pCat.x=ecran->w/2 - (Cat[CATD].Surface->w/4) /2;
    pCat.y=ecran->h - Cat[CATD].Surface->h;
    
    while(continuer)
    {
       SDL_PollEvent(&event);
       
       switch(event.type)
       {
          case SDL_QUIT:
               continuer = 0;
          break;
          case SDL_KEYDOWN:
           switch(event.key.keysym.sym)
            {
                
            }
          break;
       }
     
     SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
     
      SDLP_BlitAnim(&Cat[CATD], ecran, pCat);
      SDLP_BlitAnim(&Cat[CATG], ecran, pCat);
     
     SDL_Flip(ecran);
    
    }
    SDLP_FreeAnim(&Cat[CATD]); // On libere la surface d'Anim.
    SDLP_FreeAnim(&Cat[CATG]);
 
    SDL_Quit();
    return EXIT_SUCCESS;
}

Vous pouvez compiler mais il n'y aura rien d'habituel...


Voyez que vous pouvez utiliser un tableau pour plusieurs animations. J'ai Cat[CATD] et Cat[CATG].
Parti de ce code, nous allons faire une animation par événement.

D'abord, régler l'option de l'animation. Dans la fonction SDLP_LoadAnim:

Code : C
1
2
SDLP_LoadAnim(&Cat[CATD], "CatD.png", 4, 200, SDLP_GAUCHE, SDLP_INFINI, SDLP_NORMAL); // On charge Anim.
SDLP_LoadAnim(&Cat[CATG], "CatG.png", 4, 200, SDLP_GAUCHE, SDLP_INFINI, SDLP_NORMAL);

Maintenant, vous allez remplacer NORMAL par TOUCHE pour montrer à la fonction que nous prenons l'option Animation Par Evénement.

Code : C
1
2
SDLP_LoadAnim(&Cat[CATD], "CatD.png", 4, 200, SDLP_GAUCHE, SDLP_INFINI, SDLP_TOUCHE); // On charge Anim.
SDLP_LoadAnim(&Cat[CATG], "CatG.png", 4, 200, SDLP_GAUCHE, SDLP_INFINI, SDLP_TOUCHE);

à l'aide d'une fonction appelée SDLP_Touch, vous allez pouvoir gérer ce dernier sans rien faire, la fonction fait tout ;) .
Prototype:

Code : C
1
void SDLP_Touch(SDL_Event event, SDLP_Anim *str);


Voilà, il reste plus qu'à placer la fonction et le tour est joué !
Heureusement, j'ai anticipé ce problème pour vous et vous devrez le placer après le switch event.type comme ceci :

Code : C
1
2
3
4
5
6
switch (event.type)
   {
      /* Evenements */
   }
  SDLP_Touch(event, &Cat[CATD]);
  SDLP_Touch(event, &Cat[CATG]);

Plus tard, vous allez devoir programmer le chat qui court.
Or j'ai fait le programme avant vous et je me suis rencontré sur un problème. Quand je cliquais sur une touche autre que droite ou gauche, le chat faisait l'animation sans bouger. C'est à cause de cela (ou grâce) que j'ai créé la fonction suivante:

Code : C
1
void SDLP_BlockTouch(SDLP_Anim *str, int Commande);


Mais comment marche cette fonction ?

C'est très facile ! Elle bloque l'animation : De la déclaration de la fonction jusqu'au prochain evenement.

Exercice : Terminer le programme



Maintenant, je vous laisse programmer le chat. il doit pouvoir courir lorsqu'on appui sur la touche droite ou gauche !
Et qu'il se déplace bien entendu sinon, on croirait qu'il est sur de la glace et qu'il patine :lol:
Si vous avez bien écouté, vous devriez pouvoir y arriver.
Vous pouvez changer le code comme vous voulez et même tout recommencer, c'est ce que je vous conseille d'ailleurs ! A vous de choisir ;)

Vous êtes fin prêt maintenant !

Correction



Voilà la correction de mon casse-tête ^^
Vous n'étiez pas obliger de faire exactement la même chose.
Si vous ne comprenez pas mon code, relisez le chapitre avec plus de concentrations.

Secret (cliquez pour afficher)


Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
                               CATMAN.C                                      
                          Créé par POPOP99O0                                                      
*/

#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDLP_Anim.h>

#define CATD      0
#define CATG      1
#define DROITE    2
#define GAUCHE    3
#define VITESSE   5
// Déclaration de defines

int main(int argc, char *argv[])
{
    SDL_Surface *ecran = NULL;
    SDLP_Anim Cat[2]; // variables de la structure SDLP_Anim
    SDL_Rect pCat;
    SDL_Event event;
    int continuer = 1, Regarde = DROITE;
    
    SDL_Init(SDL_INIT_VIDEO); 
    
    ecran = SDL_SetVideoMode(400, 400, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); 
    SDL_WM_SetCaption("SDLP_Anim - Evenement", NULL);
    
    SDLP_LoadAnim(&Cat[CATD], "CatD.png", 4, 500/VITESSE, SDLP_GAUCHE, SDLP_INFINI, SDLP_TOUCHE); // On charge Anim.
    SDLP_LoadAnim(&Cat[CATG], "CatG.png", 4, 500/VITESSE, SDLP_GAUCHE, SDLP_INFINI, SDLP_TOUCHE);
    
    pCat.x=ecran->w/2 - (Cat[CATD].Surface->w/4) /2;
    pCat.y=ecran->h - Cat[CATD].Surface->h;
    /*
    Remarquez qu'on aurait pu faire aussi :
    pCat.x=ecran->w/2 - (Cat[CATG].Surface->w/4) /2;
    pCat.y=ecran->h - Cat[CATG].Surface->h;
    Ce qui est exactement la même chose !
    */
    
    SDL_EnableKeyRepeat(10, 10); /* Activation de la répétition des touches */
    
    while(continuer)
    {
       SDL_PollEvent(&event);
       
       switch(event.type)
       {
          case SDL_QUIT:
               continuer = 0;
          break;
          case SDL_KEYDOWN:
           switch(event.key.keysym.sym)
            {
                case SDLK_RIGHT:
                     pCat.x+=VITESSE;
                     Regarde=DROITE;
                break;
                case SDLK_LEFT:
                     pCat.x-=VITESSE;
                     Regarde=GAUCHE;
                break;
                default:
                     SDLP_BlockTouch(&Cat[CATD], SDLP_BLOCKED);
                     SDLP_BlockTouch(&Cat[CATG], SDLP_BLOCKED);
                break;
            }
          break;
       }
      SDLP_Touch(event, &Cat[CATD]);
      SDLP_Touch(event, &Cat[CATG]);
     
     SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
     
     switch (Regarde)
     {
      case DROITE:
         SDLP_BlitAnim(&Cat[CATD], ecran, pCat);
      break;
      case GAUCHE:
         SDLP_BlitAnim(&Cat[CATG], ecran, pCat);
      break;
     }
     
     SDL_Flip(ecran);
    
    }
    SDLP_FreeAnim(&Cat[CATD]); // On libere la surface d'Anim.
    SDLP_FreeAnim(&Cat[CATG]);
 
    SDL_Quit();
    return EXIT_SUCCESS;
}





Changez à volonté la valeur de VITESSE, plus vous irez vite, plus le chat fera de mouvements !

Allez, maintenant, un petit Q.C.M pour voir si vous avez compris. Statistiques :

Q.C.M.

Indiquer le sens de lecture quand je rentre SDLP_GAUCHE dans la fonction LoadAnim
Quelle est la fonction qui bloque l'animation meme si on clique sur une touche ?
Que pourrait-bien faire ce code à la compilation ?
Sachant que le reste du code est correct et que une variable de type SDLP_Anim a été déclarée.
Code : C
1
SDLP_BlitAnim(&Anim, ecran);
Pour qu'une animation soit autonome, on utilise
Je veux créer une variable de type animation. Que dois-je utiliser ?

Statistiques de réponses au QCM


Voilà, j'espère que vous avez tout retenu (mais je vous laisse revenir au cas où... :p ).
Y'a pas mal de fonctions que je ne vous oblige pas à toutes les retenir !

C'est ici que nous nous quittons :(
J'espère vous avoir aidé dans vos recherches :)
Au revoir mes chers amis...
Retour en haut Retour en haut


Créé : le 30/03/2008 à 11:18:31
Modifié : Aujourd'hui à 18:30:11
Avancement : 95%
Nb de visites : 1976
Licence : Copie non autorisée

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | Fil RSS | XHTML 1.0 | CSS 2.0
Édité par Simple IT SARL : Nous contacter | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 562 Zéros connectés | Requêtes SQL 9 requêtes | Temps de génération de la page : Total (SQL) 0.0304s (0.0193s)