fichiers utilisees pour la création d'un labyrinthe 3D
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Fri Jul 29 2022 08:53:21 by
![doxygen](doxygen.png)