
Le code (principales fonctions) :
I//--------------------------------------------------------------------------------------------
// * Thread AFFICHAGE *
//--------------------------------------------------------------------------------------------
static void * fn_affichage (void * p_data)
{
printf("Début Th Affichage \n");
int halt=0;
while(!halt)
{
int dep=SDL_GetTicks();
// test de fin (stop = variable partagée)
pthread_mutex_lock (& mutex_pos);
if(stop) halt=1;
pthread_mutex_unlock (& mutex_pos);
Affichage();
int fin=SDL_GetTicks();
// période de boucle fixe à t_frame
if((fin-dep)<t_frame)
{
SDL_Delay(t_frame-(fin-dep));
}
}
printf("Fin Th Affichage \n");
return NULL;
}
void Affichage()
{
printf(" >>> Début Affichage %i \n", (int)SDL_GetTicks());
blit(Fond,0,0); // Affichage Billard
switch (phase)
{
case 1: // Affichage de l'environnement complet
affBoules();
pthread_mutex_lock (& mutex_pos);
// protection variables partagées
affEnv(); // Affichage de l'environnement
// fin de protection variables partagées
pthread_mutex_unlock (& mutex_pos);
break;
case 2: // Phase Calcul boucle 1ms (mouv == 1)
affBoules(); // Affichage Boules uniquement
break;
case 3: // TO DO
break;
}
SDL_Flip(ecran);
printf(" >>> Fin Affichage %i \n", (int)SDL_GetTicks());
}
void affBoules()
{
// Création de variables locales pour ne pas allonger le mutex
int xb, yb, xp, yp, xr, yr;
/* Debut de la zone protegee. */
pthread_mutex_lock (& mutex_pos);
// On récupère les variables partagées
xb=BBx; yb=BBy;
xp=BPx; yp=BPy;
xr=BRx; yr=BRy;
/* Fin de la zone protegee. */
pthread_mutex_unlock (& mutex_pos);
// On travaille avec les variables locales
blit_tr(Boule_b, xb-13, yb-13, 52,138,65);
blit_tr(Boule_b, xp-13, yp-13, 52,138,65);
blit_tr(Boule_r, xr-13, yr-13, 52,138,65);
}
void blit_tr(SDL_Surface *image,int x,int y,int r,int g,int b) // blit avec transparence
{
position.x=x;
position.y=y;
SDL_SetColorKey(image,SDL_SRCCOLORKEY,SDL_MapRGB(image->format,r,g,b));
SDL_BlitSurface(image, NULL, ecran, &position);
}
//--------------------------------------------------------------------------------------------
// * BOUCLE PRINCIPALE *
//--------------------------------------------------------------------------------------------
void boucle()
{
while (!quitter)
{
if(mouv)
{
SDL_EventState(SDL_KEYDOWN, SDL_IGNORE);
SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE);
Calcul();
}
else
{
SDL_EventState(SDL_KEYDOWN, SDL_ENABLE);
SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE);
if(init) setInit();
WaitEvent();
}
// transmissions positions boules
pthread_mutex_lock (& mutex_pos);
if(mouv) phase=2;
else phase=1;
BBx=BoulB->px; BBy=BoulB->py;
BPx=BoulP->px; BPy=BoulP->py;
BRx=BoulR->px; BRy=BoulR->py;
pthread_mutex_unlock (& mutex_pos);
}
}
void WaitEvent()
{
if(SDL_WaitEvent(&event))
{
switch (event.type)
{
case SDL_QUIT: // exit
quitter = 1;
break;
case SDL_MOUSEBUTTONUP:
gesClic();
break;
case SDL_MOUSEMOTION:
gesMotion();
break;
case SDL_USEREVENT:
gesUser();
break;
case SDL_KEYDOWN:
gesKey();
break;
} // end switch
} // (SDL_WaitEvent(&event))
}
int Calcul()
{
// Appel cadencé à 1ms
printf("\n > Calcul %i \n", (int)SDL_GetTicks());
int attente;
int dep=SDL_GetTicks();
int fin=0;
// Actualisation vitesse et positions
actBoule(BoulP); actBoule(BoulB); actBoule(BoulR);
// Test et gestion collisions entre boules
colBoule(BoulB, BoulP);
colBoule(BoulB, BoulR);
colBoule(BoulR, BoulP);
// Tests de collision bandes
colBande(BoulP); colBande(BoulB); colBande(BoulR);
// Test de fin de mouvement
if(BoulP->mouv==0 && BoulB->mouv==0 && BoulR->mouv==0) mouv=0;
Time++;
// Boucle d'attente 1 ms
while(SDL_GetTicks()==dep)
{
attente=1; // dep + 1ms
}
return fin;
}
void actBoule(Boule *Bl)
{
if(Bl->mouv)
{
// Actualisation position
Bl->prx = (Bl->prx + Bl->Vx);
Bl->pry = (Bl->pry + Bl->Vy);
Bl->px = (int)Bl->prx;
Bl->py = (int)Bl->pry;
if(Bl->px<40+13) Bl->px=53;
if(Bl->px>1240-14) Bl->px=1226;
if(Bl->py<40+13) Bl->py=53;
if(Bl->py>639-14) Bl->py=625;
// Actualisation et amortissement vitesse
double Modi=getMod(Bl->Vix,Bl->Viy);
//printf("Modi %f \n", Modi);
static double NMod;
NMod=Modi-Kvf*(Time-Bl->tdep);
//printf(" NMod : %f ", NMod);
double coef=1.0;
if(NMod<0.000001)
{
// Arrêt du mouvement
Bl->mouv=0;
}
else
{
coef=NMod/Modi;
Bl->Vx=Bl->Vix*coef;
//printf("Vx %f ",Bl->Vx);
Bl->Vy=Bl->Viy*coef;
//printf("Vy %f ",Bl->Vy);
}
}
}
void colBoule(Boule *B1, Boule *B2)
{
// Distance entre les centres des boules
double cx1 = B1->prx;
double cy1 = B1->pry;
double cx2 = B2->prx;
double cy2 = B2->pry;
double distance=sqrt((cx2-cx1)*(cx2-cx1)+(cy2-cy1)*(cy2-cy1));
if(distance<27) // Collision !
{
printf("distance : %f \n", distance);
recale(B1, B2);
// Composantes vitesse initiale
double dx1 = B1->Vx;
double dy1 = B1->Vy;
double dx2 = B2->Vx;
double dy2 = B2->Vy;
// Module des 2 vitesses
double v1=sqrt(dx1*dx1+dy1*dy1);
double v2=sqrt(dx2*dx2+dy2*dy2);
// Positions G1 et G2 lors du choc
double nx = (cx2-cx1)/27.0; // 27 = diamètre boule
double ny = (cy2-cy1)/27.0;
double gx = -ny;
double gy = nx;
double v1n = nx*dx1*v1 + ny*dy1*v1;
double v1g = gx*dx1*v1 + gy*dy1*v1;
double v2n = nx*dx2*v2 + ny*dy2*v2;
double v2g = gx*dx2*v2 + gy*dy2*v2;
// Composante après choc
dx1 = nx*v2n+gx*v1g;
dy1 = ny*v2n+gy*v1g;
dx2 = nx*v1n+gx*v2g;
dy2 = ny*v1n+gy*v2g;
// Mise à jour des nouvelles vitesses
B1->Vix = dx1;
B1->Vx = dx1;
B1->Viy = dy1;
B1->Vy = dy1;
B2->Vix = dx2;
B2->Vx = dx2;
B2->Viy = dy2;
B2->Vy = dy2;
B1->tdep = Time;
B2->tdep = Time;
v1=sqrt(dx1*dx1+dy1*dy1);
if(v1>0.0001) B1->mouv = 1;
else B1->mouv = 0;
v2=sqrt(dx2*dx2+dy2*dy2);
if(v2>0.0001) B2->mouv = 1;
else B2->mouv = 0;
}
}
void recale(Boule *B1, Boule *B2)
{
double distance;
double cx1 = B1->prx;
double cy1 = B1->pry;
double cx2 = B2->prx;
double cy2 = B2->pry;
// repositionnement à l'endroit du choc
do
{
cx1 = cx1 - Kr*B1->Vx;
cy1 = cy1 - Kr*B1->Vy;
cx2 = cx2 - Kr*B2->Vx;
cy2 = cy2 - Kr*B2->Vy;
distance=sqrt((cx2-cx1)*(cx2-cx1)+(cy2-cy1)*(cy2-cy1));
}
while(distance<27);
printf("distance recalée : %f \n", distance);
B1->prx = cx1;
B1->pry = cy1;
B2->prx = cx2;
B2->pry = cy2;
}
int colBande(Boule *Bl)
{
int ret=0;
int retour=0;
double Kab=0.5; // coef de perte de vitesse dans le rebond
if(Bl->prx<53)
{
ret=1;
Bl->Vx=-Bl->Vx*Kab;
Bl->Vix=Bl->Vx;
Bl->prx=53;
Bl->Vy=Bl->Vy*Kab;
Bl->Viy=Bl->Vy;
}
if(Bl->prx>1226)
{
ret=1;
Bl->Vx=-Bl->Vx*Kab;
Bl->Vix=Bl->Vx;
Bl->prx=1226;
Bl->Vy=Bl->Vy*Kab;
Bl->Viy=Bl->Vy;
}
if(Bl->pry<53)
{
ret=1;
Bl->Vy=-Bl->Vy*Kab;
Bl->Viy=Bl->Vy;
Bl->pry=53;
Bl->Vx=Bl->Vx*Kab;
Bl->Vix=Bl->Vx;
}
if(Bl->pry>625)
{
ret=1;
Bl->Vy=-Bl->Vy*Kab;
Bl->Viy=Bl->Vy;
Bl->pry=625;
Bl->Vx=Bl->Vx*Kab;
Bl->Vix=Bl->Vx;
}
if(ret)
{
retour=1;
printf(" > Col Bande ! \n");
Bl->tdep=Time;
}
ret=0;
return retour;
}