On entre maintenant dans la partie la plus intéressante.
Surtout n'oubliez pas de mettre le fichier sdlgfx.dll dans le dossier de votre
projet !
Tout d'abord, le main.c devrait ressembler à ça :
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 | #include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.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(500, 500, 32, SDL_HWSURFACE);
SDL_WM_SetCaption("Faire des rotations avec SDL_gfx", NULL);
while(continuer)
{
SDL_PollEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;
}
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
SDL_Flip(ecran);
}
SDL_FreeSurface(ecran);
SDL_Quit();
return EXIT_SUCCESS;
}
|
La première chose à faire c'est d'inclure le fichier header :
Code : C1 | #include <SDL/SDL_rotozoom.h>
|
Mais il me semble que j'ai copié 5 fichiers header ? Non ?
Oui c'est vrai. Mais comme je l'ai déjà dit dans la première partie, SDL_gfx ne sert pas qu'à faire des rotations et dans notre cas, nous n'avons besoin que de
SDL_rotozoom.h.
Maintenant regardons le prototype de la fonction permettant de faire une rotation :
Code : C1 | SDL_Surface * rotozoomSurface (SDL_Surface *src, double angle, double zoom, int smooth);
|
Le premier argument est en fait le nom de la surface à modifier.
Le deuxième est l'angle de rotation.
Le troisième est le zoom à appliquer sur la surface.
Hein ! Mais qu'est-ce que le zoom vient faire ici ?
Eh bien cette fonction permet de faire une rotation mais aussi un zoom.
C'est vrai que ce n'est pas terrible comme fonctionnement, mais il doit sûrement y avoir une raison. Si vous ne voulez pas faire de zoom, mettez
1.0.
Et enfin le quatrième argument sert à lisser la surface tournée, comme ça c'est plus joli.
Mettez
1 pour lisser, sinon mettez
0.
Maintenant qu'on a tout expliqué, voilà le code complet :
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 | #include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_rotozoom.h>
#define TEMPS 30 // Le temps qu'il y a entre chaque augmentation de l'angle.
int main(int argc, char *argv[])
{
SDL_Surface *ecran = NULL, *image = NULL, *rotation = NULL;
SDL_Rect rect;
SDL_Event event;
double angle = 0;
int continuer = 1;
int tempsPrecedent = 0, tempsActuel = 0;
SDL_Init(SDL_INIT_VIDEO);
ecran = SDL_SetVideoMode(500, 500, 32, SDL_HWSURFACE);
SDL_WM_SetCaption("Faire des rotations avec SDL_gfx", NULL);
image = SDL_LoadBMP("image.bmp");
rect.x = 150;
rect.y = 150;
while(continuer)
{
SDL_PollEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;
}
tempsActuel = SDL_GetTicks();
if (tempsActuel - tempsPrecedent > TEMPS)
{
angle += 2; //On augmente l'angle pour que l'image tourne sur elle-même.
tempsPrecedent = tempsActuel;
}
else
{
SDL_Delay(TEMPS - (tempsActuel - tempsPrecedent));
}
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
rotation = rotozoomSurface(image, angle, 1.0, 1); //On transforme la surface image.
SDL_BlitSurface(rotation , NULL, ecran, &rect); //On affiche la rotation de la surface image.
SDL_FreeSurface(rotation); //On efface la surface rotation car on va la redéfinir dans la prochaine boucle. Si on ne le fait pas, cela crée une fuite de mémoire.
SDL_Flip(ecran);
}
SDL_FreeSurface(ecran);
SDL_FreeSurface(image);
SDL_Quit();
return EXIT_SUCCESS;
}
|
Surtout n'oubliez pas d'ajouter une image dans le dossier de votre projet.
Maintenant vous pouvez compiler et lancer votre programme.
Quand je lance mon programme, l'image bouge en même temps qu'elle tourne !!!
Ah oui, j'ai oublié de vous dire : quand nous plaçons notre image, sa taille change à cause de la rotation ce qui la fait bouger.
La surface rotation change de taille ?
Oui, regardez ceci pour comprendre :

Ici on a fait une rotation, donc la taille de la surface a changé.
En revanche ici, l'image n'est pas tournée, donc la surface garde sa taille normale :
Donc il faut placer notre image en fonction de sa taille.
Voici le code :
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 | #include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_rotozoom.h>
#define TEMPS 30 // Le temps qu'il y a entre chaque augmentation de l'angle.
int main(int argc, char *argv[])
{
SDL_Surface *ecran = NULL, *image = NULL, *rotation = NULL;
SDL_Rect rect;
SDL_Event event;
double angle = 0;
int continuer = 1;
int tempsPrecedent = 0, tempsActuel = 0;
SDL_Init(SDL_INIT_VIDEO);
ecran = SDL_SetVideoMode(500, 500, 32, SDL_HWSURFACE);
SDL_WM_SetCaption("Faire des rotations avec SDL_gfx", NULL);
image = SDL_LoadBMP("image.bmp");
while(continuer)
{
SDL_PollEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;
}
tempsActuel = SDL_GetTicks();
if (tempsActuel - tempsPrecedent > TEMPS)
{
angle += 2; //On augmente l'angle pour que l'image tourne sur elle-même.
tempsPrecedent = tempsActuel;
}
else
{
SDL_Delay(TEMPS - (tempsActuel - tempsPrecedent));
}
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
rotation = rotozoomSurface(image, angle, 1.0, 1); //On transforme la surface image.
//On positionne l'image en fonction de sa taille.
rect.x = 200 - rotation->w / 2;
rect.y = 200 - rotation->h / 2;
SDL_BlitSurface(rotation , NULL, ecran, &rect); //On affiche la rotation de la surface image.
SDL_FreeSurface(rotation); //On efface rotation car on va la redéfinir dans la prochaine boucle. Si on ne le fait pas, cela crée une fuite de mémoire.
SDL_Flip(ecran);
}
SDL_FreeSurface(ecran);
SDL_FreeSurface(image);
SDL_Quit();
return EXIT_SUCCESS;
}
|
Et voilà ! On a réussi à faire notre rotation. Alors, des questions ?
Euh... oui. Dans la fonction rotozoomSurface, est-ce qu'on n'aurait pas pu mettre "image = rotozoomSurface(image, angle, 1.0, 1);" ?
C'est une très bonne question. En fait oui, normalement on aurait pu le faire, mais on ne peut pas à cause du zoom parce que si à chaque fois on refait un zoom sur la même surface, alors l'image va gR
ANDIR jusqu'à l'infini, voilà pourquoi.
Quand dans la fonction on met
1.0, c'est pour agrandir l'image à sa taille normale. Si on met
0, l'image ne s'affiche pas, car on ne fait pas de zoom.
Un petit exercice
Maintenant on pourrait ajouter un petit gadget dans notre programme pour que vous vous rendiez compte de ce que l'on peut faire d'intéressant avec SDL_gfx.
Par exemple, ça serait bien que l'image bouge avec la souris. Et pour faire encore mieux, on pourrait aussi ajouter un effet de zoom.
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 | #include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_rotozoom.h>
#define TEMPS 30 // Le temps qu'il y a entre chaque augmentation de l'angle.
int main(int argc, char *argv[])
{
SDL_Surface *ecran = NULL, *image = NULL, *rotation = NULL;
SDL_Rect rect;
SDL_Event event;
double angle = 0;
double zoom = 1;
int sens = 1;
int continuer = 1;
int tempsPrecedent = 0, tempsActuel = 0;
SDL_Init(SDL_INIT_VIDEO);
ecran = SDL_SetVideoMode(500, 500, 32, SDL_HWSURFACE);
SDL_WM_SetCaption("Faire des rotations avec SDL_gfx", NULL);
image = SDL_LoadBMP("image.bmp");
while(continuer)
{
SDL_PollEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;
}
tempsActuel = SDL_GetTicks();
if (tempsActuel - tempsPrecedent > TEMPS)
{
angle += 2; //On augmente l'angle pour que l'image tourne sur elle-même.
tempsPrecedent = tempsActuel;
}
else
{
SDL_Delay(TEMPS - (tempsActuel - tempsPrecedent));
}
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
rotation = rotozoomSurface(image, angle, zoom, 0); //On transforme la surface image.
//On repositionne l'image en fonction de sa taille.
rect.x = event.button.x - rotation->w / 2;
rect.y = event.button.y - rotation->h / 2;
SDL_BlitSurface(rotation , NULL, ecran, &rect); //On affiche la rotation de la surface image.
SDL_FreeSurface(rotation); //On efface la surface rotation car on va la redéfinir dans la prochaine boucle. Si on ne le fait pas, cela crée une fuite de mémoire.
if(zoom >= 2){sens = 0;}
else if(zoom <= 0.5){sens = 1;}
if(sens == 0){zoom -= 0.02;}
else{zoom += 0.02;}
SDL_Flip(ecran);
}
SDL_FreeSurface(ecran);
SDL_FreeSurface(image);
SDL_Quit();
return EXIT_SUCCESS;
}
|