fichiers utilisees pour la création d'un labyrinthe 3D

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GAME_ENGINE.cpp Source File

GAME_ENGINE.cpp

00001 #include "GAME_ENGINE.h"
00002 
00003 LCD_DISCO_F746NG lcd;
00004 
00005 int active_layer = 0;
00006 
00007 void screen_init()
00008 {
00009     lcd.Clear(LCD_COLOR_BLACK);
00010     BSP_LCD_SelectLayer(active_layer); 
00011     BSP_LCD_SetLayerVisible(active_layer, ENABLE); 
00012     BSP_LCD_SetLayerVisible((active_layer+1)%2, DISABLE); 
00013 }
00014 
00015 uint32_t ARGBtoColor(int A,int R,int G,int B)
00016 {
00017     //A correspond à la transparence
00018     return (uint32_t) (A*(1<<24)+R*(1<<16)+G*(1<<8)+B);
00019 }
00020 
00021 void draw_seg_v(int c, int l1, int l2, color couleur)
00022 {
00023     /*
00024         c : coordonnée x
00025         i : coordonnée y
00026         et couleur
00027     */
00028     for(int i=0;i<271;i++)
00029     {
00030         if(i>l1 && i<l2)
00031         {
00032             if(couleur == 2)
00033             {
00034                 lcd.DrawPixel(c,i,ARGBtoColor(255,146,72,0));
00035             }
00036             else if(couleur == 1)
00037             {
00038                 lcd.DrawPixel(c,i,ARGBtoColor(255,0,180,0));
00039             }
00040             else
00041             {
00042                 lcd.DrawPixel(c,i,ARGBtoColor(255,0,0,0));
00043             }
00044         }
00045         else
00046         {
00047             lcd.DrawPixel(c,i,ARGBtoColor(255,0,0,0));
00048         }
00049     }
00050 }
00051 
00052 //Commandes pour se déplacer
00053 void arrow_up(position *pos,double vx,double vy)
00054 {
00055     pos->x += vx;
00056     pos->y += vy;
00057 }
00058 
00059 void arrow_down(position *pos,double vx,double vy)
00060 {
00061     pos->x -= vx;
00062     pos->y -= vy;
00063 }
00064 
00065 void rotation(double *vx,double *vy, double theta)
00066 {
00067     double tvx = *vx;
00068     double tvy = *vy;
00069     *vx = cos(theta)*tvx + sin(theta)*tvy;
00070     *vy = - sin(theta)*tvx + cos(theta)*tvy;
00071 }
00072 
00073 void arrow_right(double *vx,double *vy)
00074 {
00075     rotation(&(*vx),&(*vy),0.5);
00076 }
00077 void arrow_left(double *vx,double *vy)
00078 {
00079     rotation(&(*vx),&(*vy),0.5);
00080 }
00081 //
00082 
00083 color tangent_wall_h(double xprime, int yprime, double vy, worldmap map)
00084 {
00085     int i=(int) (xprime/WALL_SIZE), j=yprime/WALL_SIZE;
00086     if (vy<0){
00087         j--;
00088     }
00089     if ((i<0)||(j<0)||(i>=MAP_WIDTH)||(j>=MAP_HEIGHT)){
00090         /* sortie de la carte */
00091         return 3; 
00092     }else{
00093         return map[j][i];
00094     }
00095 }
00096 
00097 color tangent_wall_v(int xprime, double yprime, double vx, worldmap map)
00098 {
00099     int j = xprime / WALL_SIZE;
00100     int i = (int) (yprime / WALL_SIZE);
00101     if (vx < 0) {
00102         j--;
00103     }
00104     
00105     if (i < 0 || i >= MAP_WIDTH || j < 0 || j >= MAP_HEIGHT) {
00106         return 3;
00107     } else {
00108         return map[i][j];
00109     }
00110 }
00111 
00112 dist_and_color dda_v(position pos, double vx, double vy, worldmap map)
00113 {
00114     dist_and_color dc;
00115     int i=pos.x/WALL_SIZE,di=1;
00116     if (vx>0){
00117         i++;
00118     }else{
00119         di=-1;
00120     }
00121     double dx=fabs(WALL_SIZE*i-pos.x);  /* distance horizontale au premier bord
00122     vertical dans la direction d'observation (en pixels) */
00123     double d1;  /* distance au premier bord vertical dans la direction d'observation (en pixels) */
00124     double Dy=vy/fabs(vx); /* distance verticale (en cases)
00125     parcourue quand une case est parcourue horizontalement */
00126     double du=WALL_SIZE*sqrt(1+Dy*Dy); /* increment de distance lors du passage
00127     au bord vertical suivant (en pixels) */
00128     if (vx==0)
00129     { /* dans le cas dégénéré où la direction d'observation
00130         est pile verticale */
00131         dc.distance = INFINITY;
00132         dc.color=tangent_wall_v( pos.x, pos.y, vx, map);
00133         return dc;
00134     }
00135     pos.y += dx*Dy; /* first vertical line crossing coordinate */
00136     d1 = dx*du/WALL_SIZE;
00137     dc.distance = d1;
00138     
00139     while ((dc.color=tangent_wall_v( WALL_SIZE*i, pos.y, vx, map))==0){
00140         i += di;
00141         pos.y += WALL_SIZE*Dy;
00142         dc.distance += du;
00143     }
00144     return dc;  
00145 }
00146 
00147 dist_and_color dda_h(position pos, double vx, double vy, worldmap map)
00148 {
00149     dist_and_color dc;
00150     int j=pos.y/WALL_SIZE,dj=1;
00151     if (vy>0){
00152         j++;
00153     }else{
00154         dj=-1;
00155     }
00156     double dy=fabs(WALL_SIZE*j-pos.y); /* distance verticale au premier bord
00157     horizontal dans la direction d'observation (en pixels) */
00158     double d1; /* distance au premier bord horizontal dans la direction d'observation (en pixels) */
00159     double Dx = vx/fabs(vy); /* distance horizontale (en cases)
00160     parcourue quand une case est parcourue verticalement */
00161     double du=WALL_SIZE*sqrt(1+Dx*Dx); /* increment de distance lors du passage
00162     au bord horizontal suivant (en pixels) */
00163     if (vy==0){ /* dans le cas dégénéré où la direction d'observation
00164         est pile horizontale, on évite éventuellement la division par 0 */
00165         dc.distance = INFINITY;
00166         dc.color=tangent_wall_h( pos.x, pos.y, vy, map);
00167         return dc;
00168     }
00169     pos.x += dy*Dx; /* first horizontal line crossing coordinate */
00170     d1 = dy*du/WALL_SIZE;   
00171     dc.distance = d1;
00172     while ((dc.color=tangent_wall_h( pos.x, WALL_SIZE*j, vy, map))==0)
00173     {
00174         j += dj;
00175         pos.x += WALL_SIZE*Dx;
00176         dc.distance += du;
00177     }
00178     return dc;  
00179 }
00180 
00181 
00182 dist_and_color dda(position pos,double vx, double vy,worldmap map)
00183 {
00184     dist_and_color v = dda_v(pos,vx,vy,map);
00185     dist_and_color h = dda_h(pos,vx,vy,map);
00186     if(v.distance < h.distance)
00187     {
00188         return v;
00189     }
00190     else
00191     {
00192         return h;
00193     }
00194 }
00195 
00196 void display(position pos, double vx, double vy, worldmap map)
00197 {
00198     active_layer = (active_layer+1)%2;
00199     BSP_LCD_SelectLayer(active_layer);
00200     int hauteur;
00201     dist_and_color dc;
00202     rotation(&vx,&vy, M_PI/6);
00203     for(int i=0;i<SCREEN_WIDTH;i++)
00204     { 
00205         dc = dda(pos,vx,vy,map);
00206         hauteur = (int)WALL_SIZE*SCREEN_HEIGHT/dc.distance;
00207         hauteur = hauteur/fabs(cos((30-60*i/SCREEN_WIDTH)*2*M_PI/360));
00208         
00209         if(hauteur>SCREEN_HEIGHT)
00210         {
00211             hauteur = SCREEN_HEIGHT;
00212         }
00213         draw_seg_v(i,(SCREEN_HEIGHT-hauteur)/2,(hauteur+SCREEN_HEIGHT)/2,dc.color);
00214         rotation(&vx,&vy,2*M_PI-M_PI/3/SCREEN_WIDTH);
00215     }
00216     BSP_LCD_SetLayerVisible((active_layer+1)%2, DISABLE);
00217     
00218     BSP_LCD_SetLayerVisible(active_layer, ENABLE); 
00219 }
00220 
00221 int getInputState(inputState *iS)
00222 {
00223     TS_StateTypeDef TS_State;
00224     BSP_TS_GetState(&TS_State);
00225     if (TS_State.touchDetected==1) {
00226         iS->x =TS_State.touchX[0];
00227         iS->y =TS_State.touchY[0];
00228         return 1;
00229     }
00230     return 0;
00231 }
00232 
00233 //  
00234 //Generation du labyrinhe
00235 //
00236 //
00237 
00238 void createMap(minimap mini, worldmap world)
00239 {
00240     int i = 0;
00241     int j = 0;
00242     int k = 0;
00243     int memPosition = 0;
00244     int memi[LONGUEUR*LARGEUR]; //memoire de la coordonnee i
00245     int memj[LONGUEUR*LARGEUR]; //memoire de la coordonnee j
00246     int memalea[4] = {0,0,0,0}; //memoire des alea non utilisable
00247 
00248     float alea = 0;
00249     int aleaInt = 0;
00250     
00251     int verif = -1;
00252     
00253     //creation du labyrinthe mini de facon aleatoire
00254     
00255     for(i=0;i<LARGEUR;i++)
00256     {
00257         for(j=0;j<LONGUEUR;j++)
00258         {
00259             mini[i][j] = 15;
00260         }
00261     }
00262     
00263     int compteur = 0; //compteur pour savoir le nombre de cases que nous avons fait
00264     do
00265     {
00266         i = rand()%LONGUEUR;
00267         j = rand()%LARGEUR;
00268         alea = rand()%4;
00269         if((alea == 0 & j == 0) | 
00270             (alea == 1 & i == LONGUEUR - 1) | 
00271             (alea == 2 & j == LARGEUR - 1) | 
00272             (alea == 3 & i == 0))
00273         {
00274             verif = -1;
00275         }
00276         else
00277         {
00278             verif = 0;
00279         }
00280         
00281     }while(verif == -1);
00282     
00283     memi[memPosition] = i;
00284     memj[memPosition] = j;
00285     
00286     mini[i][j] += 16;   //bit de verif de la case mis à 1
00287     
00288     mini[i][j] -= pow(2, alea); //ouverture d'un des murs
00289    
00290     memPosition += 1;
00291     compteur += 1;
00292     
00293     aleaInt = alea;
00294     switch(aleaInt)
00295     {
00296         case 0:
00297         j--;
00298         alea = 2;
00299         aleaInt = 2;
00300             break;  
00301         case 1:
00302         i++;
00303         alea = 3;
00304         aleaInt = 3;
00305             break;
00306         case 2:
00307         j++;
00308         alea = 0;
00309         aleaInt = 0;
00310             break;
00311         case 3:
00312         i--;
00313         alea = 1;
00314         aleaInt = 1;
00315             break;
00316         default:
00317             break;
00318     }
00319     
00320     mini[i][j] -= pow(2, alea);  //ouverture de l'autre partie du mur
00321     mini[i][j] += 16;       //bit de verif de la case mis à 1
00322     memalea[aleaInt] = 1;
00323     
00324     memi[memPosition] = i;
00325     memj[memPosition] = j;
00326     memPosition += 1;
00327     compteur += 1;
00328     
00329     do
00330     {
00331         //do while pour savoir quel mur ouvrir
00332         do
00333         {
00334             alea = rand()%4;
00335             aleaInt = alea;
00336             switch(aleaInt)
00337             {
00338                 case 0:
00339                 if(j == 0)
00340                 {
00341                     memalea[aleaInt] = 1;
00342                 }
00343                 else
00344                 {
00345                     if(mini[i][j-1] >= 16)
00346                         {memalea[aleaInt] = 1;}
00347                 }
00348                     break;
00349                     
00350                 case 1:
00351                 if(i == LONGUEUR-1)
00352                 {
00353                     memalea[aleaInt] = 1;
00354                 }
00355                 else
00356                 {
00357                     if(mini[i+1][j] >= 16)
00358                         {memalea[aleaInt] = 1;}
00359                 }
00360                     break;
00361                     
00362                 case 2:
00363                 if(j == LARGEUR-1)
00364                 {
00365                     memalea[aleaInt] = 1;
00366                 }
00367                 else
00368                 {
00369                     if(mini[i][j+1] >= 16)
00370                         {memalea[aleaInt] = 1;}
00371                 }
00372                     break;
00373                     
00374                 case 3:
00375                 if(i == 0)
00376                 {
00377                     memalea[aleaInt] = 1;
00378                 }
00379                 else
00380                 {
00381                     if(mini[i-1][j] >= 16)
00382                         {memalea[aleaInt] = 1;}
00383                 }
00384                     break;
00385             }
00386             
00387             if(memalea[aleaInt] == 1)
00388             {
00389                 if(memalea[0] == 1 & 
00390                     memalea[1] == 1 & 
00391                     memalea[2] == 1 & 
00392                     memalea[3] == 1)
00393                 {
00394                     verif = 2;
00395                 }
00396                 else
00397                 {
00398                     verif = 0;
00399                 }
00400             }
00401             else
00402             {
00403                 verif = 1;
00404             }
00405         }while(verif == 0);
00406         
00407         for(k=0;k<4;k++)
00408         {   memalea[k] = 0; }
00409         
00410         switch(verif)
00411         {
00412             case 1:
00413             
00414             mini[i][j] -= pow(2, alea); //ouverture d'un des murs
00415             switch(aleaInt)
00416             {
00417                 case 0:
00418                 j--;
00419                 alea = 2;
00420                 aleaInt = 2;
00421                     break;  
00422                 case 1:
00423                 i++;
00424                 alea = 3;
00425                 aleaInt = 3;
00426                     break;
00427                 case 2:
00428                 j++;
00429                 alea = 0;
00430                 aleaInt = 0;
00431                     break;
00432                 case 3:
00433                 i--;
00434                 alea = 1;
00435                 aleaInt = 1;
00436                     break;
00437                 default:
00438                     break;
00439             }
00440             
00441             mini[i][j] -= pow(2, alea);  //ouverture de l'autre partie du mur
00442             mini[i][j] += 16;       //bit de verif de la case mis à 1
00443             memalea[aleaInt] = 1;
00444             memi[memPosition] = i;
00445             memj[memPosition] = j;
00446             memPosition += 1;
00447             compteur += 1;
00448                 break;
00449                 
00450             case 2:
00451             memPosition -= 1;
00452             i = memi[memPosition];
00453             j = memj[memPosition];
00454                 break;
00455         }
00456     }
00457     while(compteur < LONGUEUR*LARGEUR);
00458     
00459     //remplissage de world a partir de mini
00460     for(i=0;i<MAP_HEIGHT;i++)
00461     {   
00462         for(j=0;j<MAP_WIDTH;j++)
00463         {
00464             if(i == 0 || i == MAP_HEIGHT - 1 || j == 0 || j == MAP_HEIGHT - 1)
00465             {
00466                 world[i][j] = 2;
00467             }
00468             else if((i%3 == 2 || i%3 == 0) && (j%3 == 2 || j%3 == 0))
00469             {
00470                 world[i][j] = 2;
00471             }
00472             else
00473             {
00474                 world[i][j] = 0;
00475             }
00476         }
00477         
00478     }
00479     
00480     for(i=0;i<LARGEUR;i++)
00481     {
00482         for(j=0;j<LONGUEUR;j++)
00483         {
00484             verif = mini[i][j] & 0x1;   //1er bit soit mur de gauche
00485             if(verif == 0x1)
00486             {
00487                 world[3*i + 1][3*j] = 2;
00488             }
00489             
00490             verif = mini[i][j] & 0x2;   //2eme bit soit mur du bas
00491             if(verif == 0x2)
00492             {
00493                 world[3*i + 2][3*j + 1] = 2;
00494             }
00495             
00496             verif = mini[i][j] & 0x4;   //3eme bit soit mur de droite
00497             if(verif == 0x4)
00498             {
00499                 world[3*i + 1][3*j + 2] = 2;
00500             }
00501             
00502             verif = mini[i][j] & 0x8;   //4eme bit soit mur du haut
00503             if(verif == 0x8)
00504             {
00505                 world[3*i][3*j + 1] = 2;
00506             }
00507         }
00508     }
00509 }
00510 
00511 void gerenatePosition(int* i_pt, int* j_pt, worldmap world)
00512 {
00513     int i, j;
00514     int verif = 0;
00515     do
00516     {
00517         i = rand()%MAP_WIDTH;
00518         j = rand()%MAP_HEIGHT;
00519         if(i == 0)
00520         {
00521             if(world[i + 1][j] == 0)
00522             {
00523                 i ++;
00524                 verif = 1;
00525             }
00526             else
00527             {
00528                 verif = 0;
00529             }
00530         }
00531         else if(j == 0)
00532         {
00533             if(world[i][j + 1] == 0)
00534             {
00535                 j++;
00536                 verif = 1;
00537             }
00538             else
00539             {
00540                 verif = 0;
00541             }
00542         }
00543         else
00544         {
00545             verif = 0;
00546         }
00547     }while(verif != 1);
00548 
00549     *i_pt = i;
00550     *j_pt = j;
00551 }
00552 
00553 void generateSortie(int i, int j, worldmap world)
00554 {
00555     int i2 = 0;
00556     int j2 = 0;
00557     if(i == 1)
00558     {
00559         i2 = MAP_WIDTH - 1;
00560         if(j <= MAP_HEIGHT/2)
00561         {
00562             j2 = j + MAP_HEIGHT/2;
00563             while(world[i2 - 1][j2] != 0)
00564             {
00565                 j2--;
00566             }
00567             world[i2][j2] = 1;
00568         }
00569         else if(j >= MAP_HEIGHT/2)
00570         {
00571             j2 = j - MAP_HEIGHT/2;
00572             while(world[i2 - 1][j2] != 0)
00573             {
00574                 j2++;
00575             }
00576             world[i2][j2] = 1;
00577         }
00578         else
00579         {
00580             j2 = j;
00581             while(world[i2 - 1][j2] != 0)
00582             {
00583                 j2++;
00584             }
00585             world[i2][j2] = 1;
00586         }
00587     }
00588     else if(j == 1)
00589     {
00590         j2 = MAP_HEIGHT - 1;
00591         if(i <= MAP_WIDTH/2)
00592         {
00593             i2 = i + MAP_WIDTH/2;
00594             while(world[i2][j2 - 1] != 0)
00595             {
00596                 i2--;
00597             }
00598             world[i2][j2] = 1;
00599         }
00600         else if(i >= MAP_WIDTH/2)
00601         {
00602             i2 = i - MAP_WIDTH/2;
00603             while(world[i2][j2 - 1] != 0)
00604             {
00605                 i2++;
00606             }
00607             world[i2][j2] = 1;
00608         }
00609         else
00610         {
00611             i2 = i;
00612             while(world[i2][j2 - 1] != 0)
00613             {
00614                 i2++;
00615             }
00616             world[i2][j2] = 1;
00617         }
00618     }
00619 }
00620 
00621 int verificationFin(position pos, worldmap world)
00622 {
00623     int retour = 0;
00624     int i = 0;
00625     int j = 0;
00626     int k = 0;
00627     for (k = 0; k<MAP_WIDTH; k++)
00628     {
00629         if(pos.x/64>=k && pos.x/64<k + 1)
00630         {
00631             i = k;
00632         }
00633     }
00634     
00635     for (k = 0; k<MAP_HEIGHT; k++)
00636     {
00637         if(pos.y/64>=k && pos.y/64<k + 1)
00638         {
00639             j = k;
00640         }
00641     }
00642     
00643     if(world[i][j] == 1)
00644     {
00645         retour = 1;
00646     }
00647     return retour;
00648 }