Big Tuto SDL 2 - Chapitre 5 : Avec un background, c`est mieux! Big

Transcription

Big Tuto SDL 2 - Chapitre 5 : Avec un background, c`est mieux! Big
12/10/2014
Big Tuto SDL 2 - Chapitre 5 : Avec un background, c'est mieux!
Big Tuto SDL 2 - Chapitre 5 : Avec un background, c'est mieux!
Écrit par Jay | Imprimer | Affichages : 21
Note utilisateur: 0 / 5
Veuillez voter Vote 5
Note
Big Tuto SDL 2 : Rabidja v. 3.0
Chapitre 5 : Avec un background, c'est mieux !
Tutoriel présenté par : Jérémie F. Bellanger (Jay81)
Dernière mise à jour : 30 septembre 2014
Prologue
Eh, voilà !
Que... quoi ?!
Quelle magnificence !
Quelle fenêtre !
Mes aïeux !
Vous trouvez que le monochrome noir, c'est moche !
Mince alors ! Moi, qui espérais m'arrêter ici !
Non, je plaisante ! Bien sûr qu'on va la remplir notre bonne vieille fenêtre ! Et pour vous montrer ma détermination, on va tout de suite se lancer dans
l'affichage du background !
Mais c'est quoi le background ?
Non, ne me dites pas que vous êtes nul en anglais, à ce point là !?!
map, qui va rester statique.
Ah, ça me rassure ! Eh bien ça va tout simplement être le décor de fond de notre
Pour cela, il va donc nous falloir apprendre à charger, puis décharger une image à partir d'un fichier, et à l'afficher ! Non, ça ne va pas être bien dur.
Alors, on y va ! Banzaï !
Quoi ? Stop ?
Ah oui, j'allais oublier ! Comment peut-on afficher un background si on n'en a pas ?
Deux solutions s'offrent à vous : soit vous dessinez le vôtre (format 800 x 480 pixels, la taille de notre fenêtre), soit vous prenez celui-là et vous le
copiez dans le répertoire de votre projet dans le dossier graphics, sous le nom background.png (c'est important de respecter ce nom pour pouvoir le
charger dans notre programme ensuite):
background.png (faites en clic droit pour sauvegarder l'image
)
Mais, il est plus grand que 800 x 480, ce background ?!?
Eh oui, mon cher Watson ! En effet, il est 2 fois plus long, car il peut aussi se mettre en boucle et défiler en parallaxe avec la map pour donner une
impression de profondeur, fort sympathique !
Mais, on verra tout ça plus loin. Pour l'instant, on va se contenter de l'afficher tel quel, et on n'en verra donc que la moitié
(mais est-ce la meilleure
http://www.meruvia.fr/index.php/big-tuto-sdl-2-nouveau/222-big-tuto-sdl-2-chapitre-5-avec-un-background-c-est-mieux?tmpl=component&print=1&…
1/5
12/10/2014
Big Tuto SDL 2 - Chapitre 5 : Avec un background, c'est mieux!
moitié ?
- Bon, faut arrêter de se poser des questions là !
)
Le code
Nous allons commencer par introduire une nouvelle structure, dans notre header (en-tête) structs.h :
Fichier : structs.h
// Structure pour gérer la map à afficher (à compléter plus tard)
typedef struct Map
{
SDL_Texture *background;
} Map;
Il s'agit de la structure Map, que nous utiliserons, bien entendu dans le fichier du même nom (map.c) et qui contiendra les variables relatives à notre
map.
Mais c'est quoi une map ?
Cela veut dire carte, en anglais, et cela représentera ici nos niveaux, car comme sur une carte, nous aurons différents éléments placés à diverses
coordonnées bien précises.
Ici, notre première variable sera une SDL_Texture qui contiendra l'image de notre background ci-dessus.
Passons à notre main().
Fichier : main.c
int main(int argc, char *argv[])
{
unsigned int frameLimit = SDL_GetTicks() + 16;
int go;
// Initialisation de la SDL
init("Rabidja 3 - SDL 2 - www.meruvia.fr");
// Chargement des ressources (graphismes, sons)
loadGame();
// Appelle la fonction cleanup à la fin du programme
atexit(cleanup);
go = 1;
// Boucle infinie, principale, du jeu
while (go == 1)
{
//Gestion des inputs clavier
gestionInputs(&input);
//On dessine tout
drawGame();
}
// Gestion des 60 fps (1000ms/60 = 16.6 -> 16
delay(frameLimit);
frameLimit = SDL_GetTicks() + 16;
// On quitte
exit(0);
}
Vous pouvez supprimer le précédent et le remplacer par celui-là.
Vous noterez simplement 2 changements : on a 2 nouvelles fonctions :
- loadGame() qui aura pour tâche de charger toutes les ressources de notre jeu (pour l'instant, simplement le background
).
- drawGame() qui affichera toutes les tiles et tous les sprites du jeu (soit tous les éléments graphiques).
http://www.meruvia.fr/index.php/big-tuto-sdl-2-nouveau/222-big-tuto-sdl-2-chapitre-5-avec-un-background-c-est-mieux?tmpl=component&print=1&…
2/5
12/10/2014
Big Tuto SDL 2 - Chapitre 5 : Avec un background, c'est mieux!
Tile, sprite ? Kézako ?
En général, un sprite est un élément mobile du jeu qui interagit avec d'autres sprites (par exemple : le héros, les monstres, les power-ups, etc.). Au contraire, une tile est
un élément statique du décor représentant une petite partie du niveau (nos tiles feront par exemple 32x32 pixels, ce qui est une taille standard dans l'industrie du jeu vidéo
). Pour plus d'infos sur le tilemapping, je vous invite à lire cet autre tuto.
Créons désormais le fichier map.c qui se chargera de gérer notre map !
Ajoutez donc un nouveau fichier vide et nommez-le map.c.
Copiez-y le code ci-dessous :
Fichier : map.c
#include "prototypes.h"
Map map;
void initMaps(void)
{
// Charge l'image du fond (background)
map.background = loadImage("graphics/background.png");
}
SDL_Texture *getBackground(void)
{
return map.background;
}
void cleanMaps(void)
{
// Libère la texture du background
if (map.background != NULL)
{
SDL_DestroyTexture(map.background);
map.background = NULL;
}
}
Voilà, ce fichier n'est pas encore bien conséquent (mais ça va venir
) mais il contient ce dont nous avons besoin.
D'abord, vous voyez que nous déclarons notre structure map de type Map, tout en haut, que nous avons déjà défini dans defs.h.
Ensuite, nous créons 3 nouvelles fonctions (dont nous devrons ensuite ajouter les prototypes dans le fichier prototypes.h) :
- initMaps() se chargera d'initialiser toutes les variables nécessaires au bon fonctionnement de notre map. Pour l'instant, elle se chargera simplement
de charger l'image du background dans notre variable map.background à l'aide de la fonction loadImage() que nous allons écrire ci-après.
- getBackground() renvoie simplement la texture du background. Elle sera pratique pour pouvoir récupérer cette variable depuis un autre fichier,
car autrement on n'aurait pas eu le droit d'y accéder vu qu'elle est "encapsulée" dans ce fichier map.c. C'est une pratique qui sera familière à ceux qui
programment déjà de façon orientée objet (POO) avec des langages comme le C++, le C# ou le Java (entre autres).
- enfin, cleanMaps() fera le ménage à la fin du programme en supprimant de la mémoire notre fichier map.background. (C'est très important de le
faire en C, car il n'y a pas de garbage collector comme dans d'autres langages plus sophistiqués
).
Passons maintenant au fichier init.c !
Là, nous allons créer notre fonction loadGame() qui va charger notre jeu (en faisant ici simplement appel à initMaps() pour l'instant).
Fichier : init.c
void loadGame(void)
{
//On charge les données pour la map
initMaps();
}
Nous allons également compléter notre fonction cleanup(), en rajoutant un appel à cleanMaps() tout en haut :
Fichier : init.c
void cleanup()
{
http://www.meruvia.fr/index.php/big-tuto-sdl-2-nouveau/222-big-tuto-sdl-2-chapitre-5-avec-un-background-c-est-mieux?tmpl=component&print=1&…
3/5
12/10/2014
Big Tuto SDL 2 - Chapitre 5 : Avec un background, c'est mieux!
//Nettoie les sprites de la map
cleanMaps();
Bien, il ne nous reste plus maintenant qu'à gérer la partie graphique de notre programme dans le fichier draw.c. Supprimez la fonction drawGame()
(seulement celle-là) puis copiez/collez le code suivant :
Fichier : draw.c
void drawGame(void)
{
// Affiche le fond (background) aux coordonnées (0,0)
drawImage(getBackground(), 0, 0);
// Affiche l'écran
SDL_RenderPresent(getrenderer());
// Délai pour laisser respirer le proc
SDL_Delay(1);
}
SDL_Texture *loadImage(char *name)
{
/* Charge les images avec SDL Image dans une SDL_Surface */
SDL_Surface *loadedImage = NULL;
SDL_Texture *texture = NULL;
loadedImage = IMG_Load(name);
if (loadedImage != NULL)
{
// Conversion de l'image en texture
texture = SDL_CreateTextureFromSurface(getrenderer(), loadedImage);
}
else
// On se débarrasse du pointeur vers une surface
SDL_FreeSurface(loadedImage);
loadedImage = NULL;
printf("L'image n'a pas pu être chargée! SDL_Error : %s\n", SDL_GetError());
return texture;
}
void drawImage(SDL_Texture *image, int x, int y)
{
SDL_Rect dest;
/* Règle le rectangle à dessiner selon la taille de l'image source */
dest.x = x;
dest.y = y;
/* Dessine l'image entière sur l'écran aux coordonnées x et y */
SDL_QueryTexture(image, NULL, NULL, &dest.w, &dest.h);
SDL_RenderCopy(getrenderer(), image, NULL, &dest);
}
Commençons par drawGame() : vous aurez remarqué qu'on ne remplit plus l'écran en noir (même si on aurait pu le laisser avant, sans que cela ne
change grand chose
), mais qu'à la place, on appelle drawImage() pour afficher le background, renvoyé par notre fonction précédente
getBackground().
loadImage() prend en argument l'emplacement du fichier à charger (si vous avez une erreur, ou un écran noir, commencez d'ailleurs par vérifier que
votre image est au bon endroit et qu'elle a le bon nom
), elle charge ensuite le fichier comme une SDL_Surface en 2D (comme pour la SDL 1.2) avant
de la convertir en texture 3D à partir du format du renderer. L'image sera ainsi optimisée pour coller à votre renderer (qui peut par exemple recalculer la
dimension des images pour faire du plein écran) et être gérée par votre grosse carte graphique (au boulot, ma vieille !
). La SDL_Surface est ensuite
supprimée de la mémoire (important !) et la fonction renvoie la texture.
drawImage() enfin va nous servir à dessiner nos images. Cette fonction est très basique (nous en créerons une plus complexe plus tard pour gérer les
découpages, les flips et les rotations de sprites
) : elle prend une texture et ses coordonnées x et y en arguments et elle blitte (=colle) ensuite l'image
toute entière auxdites coordonnées.
Eh voilà !
N'oublions pas maintenant de compléter notre fichier prototypes.h avec nos nouveaux prototypes. Je vous redonne le fichier complet ci-dessous :
Fichier : prototypes.h
http://www.meruvia.fr/index.php/big-tuto-sdl-2-nouveau/222-big-tuto-sdl-2-chapitre-5-avec-un-background-c-est-mieux?tmpl=component&print=1&…
4/5
12/10/2014
Big Tuto SDL 2 - Chapitre 5 : Avec un background, c'est mieux!
#ifndef PROTOTYPES
#define PROTOTYPES
#include "structs.h"
/* Catalogue des prototypes des fonctions utilisées.
On le complétera au fur et à mesure. */
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
void cleanMaps(void);
void cleanup(void);
void delay(unsigned int frameLimit);
void drawGame(void);
void drawImage(SDL_Texture *, int, int);
void drawMap(int);
void gestionInputs(Input *input);
SDL_Texture *getBackground(void);
void getInput(Input *input);
SDL_Renderer *getrenderer(void);
void init(char *);
void initMaps(void);
void loadGame(void);
SDL_Texture *loadImage(char *name);
#endif
Compilez désormais le programme puis lancez-le et TADAAA !
Notre magnifique background s'affiche dans toute l'immensité de sa beauté ! (j'exagère à peine !
)
@ bientôt pour le chapitre 6 !
Jay
http://www.meruvia.fr/index.php/big-tuto-sdl-2-nouveau/222-big-tuto-sdl-2-chapitre-5-avec-un-background-c-est-mieux?tmpl=component&print=1&…
5/5