Entre explosion et fantômes |
Ce croquis suggère une curieuse matière un peu visqueuse qui apparaît sous la forme d’une explosion, s’écoule le long de l’écran et se stabilise en bas dans une sorte de flaque qui prend progressivement l’allure d’une barre, comme une épée de Jedaï dans la Guerre des Etoiles. Eventuellement, si l’écoulement n’arrive pas à son terme, la masse en forme de fuseau se resserre et s’efface progressivement, puis disparaît comme un fantôme. En
modifiant quelques paramètres on obtient toutes sortes de variations.
Cet effet est pressenti pour, par exemple, un Brodock à plumeau
( un Brodock à plumeau est une sorte de bouée hérissée
de poils explosifs, quelque chose comme un mollusque chimérique
à réaliser dans le cadre d’une galerie de logiciels
monstrueux ). |
![]() |
TELECHARGER aaaTexte des explications, aaaExecutable (Windows), aaaSource (utilise la librairie Allegro)
|
![]() |
EXPLICATIONS 1. Principe A la base il y a simplement une concentration de vecteurs, tous de sens différents, mais qui, à partir d’un centre commun donnent lieu à des projections de particules et un rayonnement. Les particules projetées sont ensuite soumises à pesanteur. Elles s’alourdissent petit à petit et l’ensemble finit par s’effondrer vers le bas. Les particules rebondissent en bas, remontent et retombent jusqu’à stabilisation. 2. Mise en forme et initialisation Les vecteurs sont réalisés sous la forme d’une structure qui comprend quatre floats et un entier. Les quatre floats sont pour la précision de calculs en nombre à virgule. Ils concernent les deux points de coordonnées du vecteur. Le premier comme origine ( x, y ) et le second comme distance qui lui est ajoutée. L’entier « couleur » stocke une couleur. Le type « VECTEUR » est défini comme suit au début du programme : aaaaatypedef
struct { Ensuite
il y a besoin d’un nombre de vecteurs. Le plus simple est d’avoir
un tableau de structures VECTEUR. Il faudra pouvoir tester le programme
avec des nombres différents de vecteurs, d’où la définition
d’une macro, ce qui donne : Notons également le besoin de nombres aléatoires à virgule. Pour ce faire la macro « frandom » est définie de la façon suivante : aaaaa#define frandom( n ) ( ( (float)rand( ) / ( float )RAND_MAX ) * ( n ) ) La
valeur de retour de la fonction « rand » est convertie en
float par un « cast » ensuite elle est divisée par
la valeur maximum que peut retourner « rand », elle-même
convertie en float ( la macro RAND_MAX est définie dans la librairie
utilitaire <stdlib.h> ). On a donc un nombre compris entre 0 et
1. Pour finir il est multiplié par « n » afin d‘avoir
un nombre entre 0 et « n » avec la précision d’un
flottant. Initialisation
des vecteurs (1)aaaaavoid
init_explosion(int x, int y) (2)aaaaaaafor(
i = 0; i < NB_VECTEURS; i++ ) { (1) La fonction « init_explosion » ne renvoie rien mais a deux paramètres, deux entiers. En fait c’est une position qui lui est passée. La fonction utilise quelques variables locales, un entier et quatre float. (2) Boucle qui passe chaque vecteur en revue. Le premier point est d’attribuer des valeurs de position et de distance à la position pour chacun des vecteurs. Les vecteurs prennent tous la même position ( x, y ) passée en argument à la fonction. La distance est aléatoire dans la fourchette de – 1 à 1 pour dx et de – 5 à 5 pour dy. (3)
A cette étape de la fonction, par rapport au centre en (x, y),
l’ensemble des vecteurs est enfermé dans un rectangle de
deux unités horizontales sur 10 verticales. Ce n’est pas
inintéressant mais l’objectif est ici de passer en coordonnées
polaires et de se situer à l’intérieur d’un
disque. (4)
En ce qui concerne la couleur nous avons opté pour que tous les
vecteurs prennent la même couleur initiale, la position 255 de la
palette. Le souhait est d’avoir au centre une couleur très
claire et qui décroisse avec l’éloignement. (1)aaaaavoid
palette(void) (1) La fonction « palette » ne prend pas d’argument et ne renvoie rien. (2) la position 0 est initialisée avec la couleur noire. (3) Des positions 1 à 63 le rouge prend une valeur au hasard entre 0 et 63. Le vert et le bleu restent à 0. (4) Des positions 64 à 127 toujours pareille pour le rouge, le vert augmente de 1 en un et le bleu reste à 0. (5) Des positions 128 à 256 le rouge est toujours aléatoire, le vert est fixé à 63 et le bleu augmente de 1 en 1 par pas de deux, l’expression i >> 1 revient à diviser i par deux et dans la fonction il faudra qu’il augmente de 2 pour avancer de 1.
aaaaaaa(…) (2)aaaaado
{ (4)aaaaaaaabouge_vecteurs
( page ); (1) Tout d’abord il y a les initialisations des globales, à savoir la palette et la page intermédiaire du montage de l’image. Ensuite un appel à la fonction « init_explosion » avec en argument la position du centre de l’écran afin de démarrer le programme sur une explosion au centre de l’écran. (2) Le type de boucle choisi est do-while de façon à ce qu’il y ait au moins une explosion même dans le cas ou la touche Echap aurait déjà été pressée, c’est en effet le test d’arrêt de la boucle ligne (5). (3) A chaque pression de la touche Entrée il y a une nouvelle initialisation avec une position aléatoire dans l’écran. (4)
Après initialisation, vient le mouvement, avec l’itération
d’une part de la fonction « bouge_vecteurs » qui anime
les vecteurs, et d’autre part, l’effet de disparition progressive
des couleurs avec la fonction « efface_progressif ». Les modifications
de l’image sont faites en mémoire avec la bitmap page et
pour finir l’image obtenue est plaquée à l’écran
avec la fonction « blit ». (1)aaaaafloat poids = 0.1; (2)aaaaavoid
bouge_vecteurs(BITMAP *bmp) (5)aaaaaaaaaa
aaav->x
+= v->dx; (1) La fonction utilise une variable « poids » ici déclarée globale afin éventuellement de pouvoir modifier sa valeur à partir d’une autre fonction dans le programme. « poids » va servir à accentuer le déplacement vers le bas de l’écran en y. (2) « bouge_vecteurs » prend une bitmap de référence en argument et ne renvoie pas de valeur. La déclaration locale d’un pointeur de type VECTEUR* est motivée afin de soulager l’écriture. Il est initialisé avec la première adresse du tableau VECT, la première position. (3) Tous les vecteurs sont passés en revue, à noter l’incrémentation parallèle du pointeur. (4)(5)
Pour chacun d’entre eux il y a d’abord les modifications de
la position verticale et ensuite les modifications de la position horizontale
en (5). Dans les deux cas la distance est ajoutée à la position
courante. Vient ensuite un test sur les bords de l’écran.
(6)
Pour finir, le vecteur qui est visualisé par le déplacement
d’un point est affiché dans la bitmap de référence
selon le principe que nous avons détaillé au chapitre Onze. (1)aaaaavoid
efface_progressif(BITMAP *bmp) aaaaaaaaaaafor
( y = 1; y < ECRAN_Y-1; y++ ) (2)aaaaaaaaaaaaaaaat
= ( bmp->line[ y-1 ][ x ] + bmp->line[ y+1 ][ x ] + (1) « efface_progressif » ne renvoie pas de valeur et a comme paramètre unique une bitmap de référence. (2) Pour chaque position de la bitmap passée en argument, une variable « t » stocke tout d’abord l’addition des quatre voisines et la divise par quatre. Ensuite l’expression conditionnelle décrémente t de 2 si t est supérieur à 2 et lui attribue 0 sinon. (3) Pour finir, t qui est de type int est casté en unsigned char et affectée à la position courante ( x, y).
|
![]() |