Au sanglier codeur

CSurface

Introduction

Les surfaces sont véritablement les briques d'un jeu en 2 dimensions.
Tout ce que vous pourrez voir à l'écran ne sera que surface rectangulaire, elles sont juste plus ou moins "arrangées". (transparence, assemblage, particules, etc...)

Il est donc primordial que la classe associée à une surface soit robuste et bien conçue.
Pas trop de souci à se faire de ce coté là, puisque nous allons réutilisé les SDL_Surface de la SDL et nous "contenter" plus ou moins de les encapsuler dans une classe. (Pour le moment ;) )

Interface

Comme dis le proverbe : en toutes choses faut-il commencement.
Alors commençons par voir de quoi sera fait le constructeur de notre classe; enfin, nous devrions plutôt dire les constructeurs. :)

Les constructeurs

Il y a plusieurs possibilités pour une surface, elle peut être de couleur unie ou représenter une image par exemple.

Pour image :

Dans le cas d'une image, il faudra la charger à partir d'un fichier, d'où ce constructeur :

CSurface(const std::string &path, Uint32 x = 0, Uint32 y = 0);


(vous voyez là le prototype des fonctions, donc il y a les valeurs par défaut)
On passe une std::string en paramètre qui va indiquer le path du fichier contenant l'image.
Puis les paramètres x et y vont servir à indiquer la position de la surface sur l'écran.

Pour surface unie :

Dans le cas où on veuille créer une surface unie, il faut un peu plus de paramètres :

CSurface(Uint32 w = 320, Uint32 h = 240, Uint32 x = 0,
Uint32 y = 0, Uint8 r = 255, Uint8 g = 255, Uint8 b = 255);


x et y restent les mêmes. w et h indiquent respectivement la largeur et la hauteur de la surface. (w pour width et h pour height)
On a dit qu'on voulait une surface de couleur unie, aussi faut il préciser cette couleur; c'est le rôle des trois derniers paramètres.
r (red) indique la valeur de la composante rouge de cette couleur, g (green) la composante verte , et b (blue) la composante bleu.

Il reste un dernier constructeur qui effectue la même chose :

CSurface(SDL_Rect rct, Uint8 r = 255, Uint8 g = 255, Uint8 b = 255);


Les paramètres concernant la couleur de la surface ne changent pas.
La différence est que les informations concernant la position et les dimensions de la surface sont regroupées dans une variable de type SDL_Rect, le paramètre rct.
Cela permet parfois de gagner du temps, ou des lignes de code.

Et d'ailleurs, nous allons devoir stocker les informations concernant la position et les dimensions de la surface.
Et pour ce faire nous allons avoir un attribut de type... SDL_Rect. (après tout il est prévu pour ça. :) )

Les autres méthodes

Les autres méthodes se contentent toutes d'encapsuler des fonctions spécifiques de la SDL : charger une nouvelle image, remplir la surface ou encore rendre une couleur transparente.

A part le destructeur qui se chargera de libérer la surface.

Il y a aussi quelques accesseurs/mutateur pour l'attribut concernant les positions et dimensions et pour la surface.

En ce qui concerne les attributs d'ailleurs, nous venons de voir les 2 seuls utiles pour le moment.
Nous en rajouterons d'autres par la suite; patience. ;)

Conclusion

Commençons par le constructeur qui permet de charger une image :

/* 01 */ m_baseSurf = NULL;
/* 02 */ m_baseSurf = kgg::CTextureManager::getInstance()->getItem(path.c_str());
/* 03 */ m_position.x = x;
/* 04 */ m_position.y = y;
/* 05 */ m_position.w = m_baseSurf->w;
/* 06 */ m_position.h = m_baseSurf->h;


Les lignes 3, 4, 5 et 6 n'ont rien de bien palpitant, les 2 premières en revanche sont un peu plus intéressantes.
Dans la première on s'assure que le pointeur m_baseSurf (l'attribut de type SDL_Surface) est bien initialisé à NULL, puis dans la 2eme, on passe par la manager de texture (vu quelques chapitres auparavant) pour charger l'image.

Et maintenant le constructeur qui permet de créer une surface de couleur unie :

/* 01 */ m_baseSurf = SDL_CreateRGBSurface(SDL_HWSURFACE, rct.w, rct.h, 32, 0, 0, 0, 0);
/* 02 */ //Si la composante r est < 0, on la met à 0
/* 03 */ r = (r < 0)?0:r;
/* 04 */ //Si elle est > à 255, on la met à 255
/* 05 */ r = (r > 255)?255:r;
/* 06 */ g = (g < 0)?0:g;
/* 07 */ g = (g > 255)?255:g;
/* 08 */ b = (r < 0)?0:b;
/* 09 */ b = (r > 255)?255:b;
/* 10 */ //Et on remplit la surface avec la bonne couleur
/* 11 */ SDL_FillRect(m_baseSurf, NULL, SDL_MapRGB(m_baseSurf->format, r, g, b));
/* 12 */ m_position = rct;


On peut voir ligne 12 que grâce au passage d'un paramètre de type SDL_Rect, il ne reste plus qu'a le copier dans l'attribut de la classe tout simplement.

On commence ligne 1 par créer la surface, en se servant au passage de la largeur et de la hauteur contenues dans le paramètre de type SDL_Rect.

Les lignes qui suivent servent à éviter les débordements au niveau de la couleur.
Nous avons dit que les composantes devaient êtres contenues entre 0 et 255, mais il arrive qu'on se trompe lors de la création de la surface ou encore qu'on ne le sache pas.

C'est pourquoi nous allons nous servir de ternaires pour vérifier que la valeur est correcte.
Rappelons le fonctionnement d'une ternaire : si la condition entre parenthèse est validée, la variable tout à gauche prendra la valeur juste après le ? ; sinon elle prendra celle juste après les : .

Ainsi pour chaque composante, on commence par vérifier que le nombre n'est pas dessous de 0, puis qu'il n'est pas au dessus de 255.
Finalement on remplit la surface avec la bonne couleur ligne 11.

Les autres méthodes présentes peu d'intérêt, mais si vous voulez voir le code, vous pouvez toujours regarder dans le code source du KGG.

Ce à quoi il faut faire bien attention, c'est de modifier les attributs qu'il faut à chaque changement.
Par exemple au chargement d'une nouvelle image pour la surface, il faut penser à modifier "à la main" l'attribut contenant la largeur et la hauteur. ;)

Conclusion

Nous venons de voir la base des CSurfaces dans notre moteur mais c'est loin d'être fini !

Il y a aussi toute une partie concernant la gestion physique et une autre concernant la gestion graphique (modification de la surface pour un ajustement des couleurs ou des effets visuels...)

La gestion physique est expliquée un peu plus loin dans le tutoriel : URL Et la gestion graphique dans la partie 4.


Valid XHTML 1.0 Strict - Le Sanglier Codeur, par GuilOooo & Kevin Leonhart - Remonter en haut - Valid CSS !