top of page

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;
}

 

 

 


 

 

© 2015 par PicoSoft. Créé avec Wix.com

bottom of page