
/**************************************************************************
ANIMATION : 10 disques bougent à l'écran (rebondissent sur les bords)
avec double buffer (pas de clignotement)
ATTENTION : CECI EST UNE PREMIERE MANIERE D'AVOIR N ELEMENTS ANIMES
EN MEME TEMPS EN UTILISANT DES TABLEAUX DE PARAMETRES.
UNE MANIERE BEAUCOUP PLUS PROPRE ET EFFICACE UTILISANT
DES TABLEAUX DE STRUCTURES SERA EXPOSE DANS LA SUITE...
**************************************************************************/
#include <allegro.h>
#include <time.h>
// Utilisation d'une constante pour le nombre d'élément.
// Une constante est nécessaire car on ne peut pas
// (en principe en C standard) utiliser une taille variable
// pour déclarer un tableau automatique.
#define NELEM 10
int main()
{
// BITMAP servant de buffer d'affichage
BITMAP *page;
// paramètres des éléments à animer (disques) : tableaux
int posx[NELEM],posy[NELEM]; // coordonnées
int rayon[NELEM]; // tailles (rayons des disques)
int depx[NELEM],depy[NELEM]; // vecteurs déplacement effectifs en x et y
int couleur[NELEM]; // couleurs des disques
int i;
// On va utiliser du hasard
srand(time(NULL));
// Lancer allegro et le mode graphique
allegro_init();
install_keyboard();
set_color_depth(desktop_color_depth());
if (set_gfx_mode(GFX_AUTODETECT_WINDOWED,800,600,0,0)!=0)
{
allegro_message("prb gfx mode");
allegro_exit();
exit(EXIT_FAILURE);
}
// CREATION DU BUFFER D'AFFICHAGE à la taille de l'écran
page=create_bitmap(SCREEN_W,SCREEN_H);
clear_bitmap(page);
// Initialisation aléatoire des paramètres des éléments
for (i=0;i<NELEM;i++){
rayon[i]=rand()%40+1;
posx[i]=rand()%(SCREEN_W-2*rayon[i])+rayon[i];
posy[i]=rand()%(SCREEN_H-2*rayon[i])+rayon[i];
// Vitesse aléatoire symétrique
// avec composantes horizontales et verticales non nulles
do
{
depx[i]=rand()%21-10;
depy[i]=rand()%21-10;
} while (depx[i]==0 || depy[i]==0);
// Couleur pas trop sombre
couleur[i]=makecol(rand()%128+128,rand()%128+128,rand()%128+128);
}
// Boucle d'animation (pas d'interaction)
while (!key[KEY_ESC])
{
// 1) EFFACER POSITIONs ACTUELLEs SUR LE BUFFER
// ON EFFACE TOUT LE BUFFER ! (c'est plus simple)
clear_bitmap(page);
// 2) DETERMINER NOUVELLEs POSITIONs
for (i=0;i<NELEM;i++){
// contrôle des bords : ici on décide de rebondir sur les bords
if ( (posx[i]-rayon[i]<0 && depx[i]<0) || (posx[i]+rayon[i]>SCREEN_W && depx[i]>0) )
depx[i]=-depx[i];
if ( (posy[i]-rayon[i]<0 && depy[i]<0) || (posy[i]+rayon[i]>SCREEN_H && depy[i]>0) )
depy[i]=-depy[i];
// calculer nouvelle position
// nouvelle position = position actuelle + deplacement
posx[i]=posx[i]+depx[i];
posy[i]=posy[i]+depy[i];
}
// 3) AFFICHAGE NOUVELLEs POSITIONs SUR LE BUFFER
// ON UTILISE page AU LIEU DE screen
for (i=0;i<NELEM;i++){
circlefill(page,posx[i],posy[i],rayon[i],couleur[i]);
}
// 4) AFFICHAGE DU BUFFER MIS A JOUR A L'ECRAN
// le nouveau contenu graphique remplace l'ancien
// sans que l'ancien ait été effacé à l'écran (pas de clignotement)
blit(page,screen,0,0,0,0,SCREEN_W,SCREEN_H);
// 5) ON FAIT UNE PETITE PAUSE à chaque fois sinon ça va trop vite...
rest(20);
}
return 0;
}
END_OF_MAIN();