[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)
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 !
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).
Bien, la 1ère chose est de télécharger notre fichier ZIP qui contient notre header pour que nos fonctions fonctionnent

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 ?
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
Un peu de sérieux dans la salle
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
Après l'installation de l'astuce, voilà ce que ça pourrait donner :

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 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.
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 : C1 | 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

) !
On va régler tout ça en mettant le double buffering
Code : C1 | ecran = SDL_SetVideoMode(200, 200, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
|
Code : C
Nous allons mettre SDL_PollEvent car une animation n'a pas besoin d'événement pour qu'elle se mette à fonctionner !
Code : C
Nous avons oublier quelque chose non ?
Ah voilà ce qui manquait !
Dans l'exemple du tutorial, on trouve ceci dans l'en-tête du fichier
.c.
Code : C1
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
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 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 : C1 | 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.
- SDLP_Anim *str : Entrez ici l'adresse de la surface de l'animation;
- char *SurfaceAnim : Entrez ici le chemin de l'exécutable à l'image;
- int nbPicture2 : Nombre d'image à séparer dans celle qui a été déclarée plus haut;
- long temps : Définir ici le temps entres chaque images (en millisecondes);
- int coter1 : Définir ici le coter de défilement. Utilisez les defines SDLP_GAUCHE ou SDLP_DROITE;
- int Loop1 : Choisir ici le nombre de fois que l'image doit être animée. Utilisez les defines SDLP_INFINI ou SDLP_LIMITE;
- int Util1 : Entrez ici si l'animation doit se jouer normalement ou en fonction qu'on appui sur une touche. Utilisez les defines SDLP_NORMAL ou SDLP_TOUCHE.
Nous verrons comment utiliser l'animation par évenement dans le chapitre 'Animation par Evenement'.
Code : C1 | 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 ?
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 : C1
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 ?
Nous allons utiliser la fonction de blittage
la plus simple qui est jamais existé
Le prototype l'est aussi :
Code : C1 | void SDLP_BlitAnim(SDLP_Anim *str, SDL_Surface *ecran, SDL_Rect pos);
|
- SDLP_Anim *str : Entrez ici l'adresse de la surface de l'animation;
- SDL_Surface *ecran : Surface qui gère la fenêtre. Souvent appelée écran ou screen;
- SDL_Rect pos : Inscrivez ici votre variable de la position de votre animation.
Et c'est tout !
J'ai fait aussi une petite fonction pour la transparence:
Code : C1 | void SDLP_SetColorKeyAnim(SDLP_Anim *str, int R, int V, int B);
|
- SDLP_Anim *str : Entrez ici la surface de l'animation;
- int R : Couleur Rouge;
- int V : Couleur Verte;
- int B : Couleur Bleu;
- Toutes les couleurs ensemble feront la couleur de transparence désirée.
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 !
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 !
Faisons courir la chaton !
Nous allons utiliser 2 images qui restaient de SDLP_Anim.zip:
Et
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 : C1
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 : C1
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 : C1 | void SDLP_Touch(SDL_Event event, SDLP_Anim *str);
|
- SDL_Event event : Variable de type SDL_Event. Gère tous les evenements;
- SDLP_Anim *str : Variable de type SDLP_Anim. Vous allez envoyer ici l'adresse de votre Variable SDLP_Anim.
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 : C1
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 : C1 | void SDLP_BlockTouch(SDLP_Anim *str, int Commande);
|
- SDLP_Anim *str : Variable de type SDLP_Anim. Vous allez envoyer ici l'adresse de votre Variable SDLP_Anim;
- int Commande : Entrez ici SDLP_BLOCKED pour bloquer l'animation.
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
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 :
- Entre 20 et 15 : Vous avez tout compris, félicitations;
- Entre 14 et 10 : Vous avez eu quelques oublies, ce n'est pas trop grave ;
- Entre 9 et 5 : ça devient très moyen et je vous demande de relire vite fait les fonctions et peut-être les résumés;
- Entre 4 et 0 : Ce n'est pas fameux, peut mieux faire, Vous devez TOUS relire encore plus attentivement pour pouvoir contrôler cet outil.
Voilà, j'espère que vous avez tout retenu (mais je vous laisse revenir au cas où...

).
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...