Collisions

On encadre l'angle de rotation sur [0 ; 2 PI]

if (rp->module_rot>_2PI) rp->module_rot = 0.0f;
if (rp->module_rot<0) rp->module_rot = _2PI;

On encadre maintenant le coefficient vitesse sur [0 ; 10]

if (rp->coef_vitesse_module<0.0f) {rp->coef_vitesse_module=0.0f; rp->collision = 0;}
if (rp->coef_vitesse_module>10) {rp->coef_vitesse_module=10; rp->collision = 0;}

Ensuite on définit les projections du vecteur diectionnel du module sur les axes Z et X, p_z et p_x.



float p_z = .3*rp->coef_vitesse_module*cos(rp->module_rot);
float p_x = .3*rp->coef_vitesse_module*sin(rp->module_rot);

Ensuite on détermine la collision entre les deux modules. On calcule la distance entre les deux centre de gravité des modules et on la compare au rayon * 2.

if (((-rp->coord_0.x)-(-rp2->coord_0.x))*((-rp->coord_0.x)-(-rp2->coord_0.x))+((-rp->coord_0.z)-(-rp2->coord_0.z))*((-rp->coord_0.z)-(-rp2->coord_0.z)) < (rp->rayon+rp2->rayon)*(rp->rayon+rp2->rayon))
rp->collision = 1;

Ici on déplace le module suivant les deux axes Z et X. On fait aussi évoluer le coefficient vitesse ainsi que celui de la caméra pour que le module s'éloigne légèrement de la caméra. Si une collision a lieu entre les deux modules (collision à 1) alors le vecteur direction V devient -V. D'où p_x = -p_x et p_z = -p_z

if (rp->collision == 1)
{
if (etm->bas==1) {rp->coord_0.z-=p_z; rp->coord_0.x+=p_x; rp->coef_vitesse_module+=.2f;rp->coef_cam-=.3; if(rp->coef_cam<-20) rp->coef_cam=-20;}
if (etm->bas==2) {rp->coord_0.z-=p_z; rp->coord_0.x+=p_x; rp->coef_vitesse_module-=.2f;rp->coef_cam+=.3; if(rp->coef_cam>0) rp->coef_cam=0;}
if (etm->haut!=0) {rp->coord_0.z+=p_z; rp->coord_0.x-=p_x; rp->coef_vitesse_module-=.2f;}
}
else
{
if (etm->haut==1) {rp->coord_0.z-=p_z; rp->coord_0.x+=p_x; rp->coef_vitesse_module+=.2f;rp->coef_cam-=.3; if(rp->coef_cam<-20) rp->coef_cam=-20;}
if (etm->bas==1) {rp->coord_0.z+=p_z; rp->coord_0.x-=p_x; rp->coef_vitesse_module+=.2f;}

if (etm->haut==2) {rp->coord_0.z-=p_z; rp->coord_0.x+=p_x; rp->coef_vitesse_module-=.2f;rp->coef_cam+=.3; if(rp->coef_cam>0) rp->coef_cam=0;}
if (etm->bas==2) {rp->coord_0.z+=p_z; rp->coord_0.x-=p_x; rp->coef_vitesse_module-=.2f;}
}

if (rp->collision == 1) {p_x*=-1; p_z*=-1;}

Les coordonnées des murs du labyrinthe sont saisis dans une liste placée au début du fichier principal .cpp.
Nous avons quatre orientations
NORD, OUEST, SUD, EST

A chaque passage, nord vers est par exemple, on effectue un changement de repère de PI/2. Ainsi on indique pour chaque face du mur le point situé à gauche sur l'axe des X ensuite celui situé à droite et enfin la position sur l'axe des Z des deux points.

float pl[30][3] =
{
{-90, 100, 100}, {0, 200, 0}, {-100, 100, -90}, {-100, 200, -200}, {-200, -100, -250}, {-190, -100, 190}, {0, 190, 190},
{190, 200, -100}, {-250, -240, -100}, {-80, 100, -90}, {100, 110, 100}, {-90, -80, 100}, {0, 200, 200}, {-200, -100, 200}, {-240, 190, -190},
{-100, -200, 200}, {200, 0, 200}, {100, -100, 110}, {190, 0, 10}, {100, -90, -80}, {200, 190, -100}, {190, -100, -190}, {-100, -190, -240},
{200, -250, -200}, {110, -90, -100}, {-190, -200, -100}, {200, 190, 0}, {10, 0, 0}, {190, 10, 190}, {-100, -190, 190},
};

Ensuite, dans la fonction rendu  on teste s'il y a collision ou non suivant l'angle d'orientation du module en déterminant s'il est orienté vers le Nord, le Sud, l'Est ou l'Ouest.
On détermine la distance entre le centre de gravité du module et l'un des deux points de la face du mur.
Ensuite on détermine la distance entre le centre de gravité du module et l'autre point de la face du mur.
Enfin on détermine la distance entre le module situé entre les deux points de la face du mur et la face du mur elle-même.
Si le teste est VRAI, on recule le module.

if ((rp->collision == 1) || ((rp->module_rot>=0 && rp->module_rot<1.5708) || (rp->module_rot>=4.7124 && rp->module_rot<6.2632)))
for(i=0; i<7; i++) 
if ((-rp->coord_0.z)+rp->rayon>pl[i][2] && (-rp->coord_0.z)-rp->rayon<pl[i][2]) {
if((-rp->coord_0.x)>pl[i][0] && (-rp->coord_0.x)<pl[i][1])
{rp->coord_0.z+=p_z; }

if((-rp->coord_0.x)+rp->rayon>pl[i][0] && (-rp->coord_0.x)-rp->rayon<pl[i][1]) {
if (((-rp->coord_0.z)-pl[i][2])*((-rp->coord_0.z)-pl[i][2])+((-rp->coord_0.x)-pl[i][0])*((-rp->coord_0.x)-pl[i][0])<rp->rayon*rp->rayon)
{rp->coord_0.z+=p_z; }

if (((-rp->coord_0.z)-pl[i][2])*((-rp->coord_0.z)-pl[i][2])+((-rp->coord_0.x)-pl[i][1])*((-rp->coord_0.x)-pl[i][1])<rp->rayon*rp->rayon)
{rp->coord_0.z+=p_z; }
}
}

if ((rp->collision == 1) || (rp->module_rot>=0 && rp->module_rot<_PI))
for(i=7; i<15; i++) 
if ((-rp->coord_0.x)+rp->rayon>pl[i][2] && (-rp->coord_0.x)-rp->rayon<pl[i][2]) {
if((-rp->coord_0.z)>pl[i][0] && (-rp->coord_0.z)<pl[i][1])
{rp->coord_0.x-=p_x; }

if((-rp->coord_0.z)+rp->rayon>pl[i][0] && (-rp->coord_0.z)-rp->rayon<pl[i][1]) {
if (((-rp->coord_0.x)-pl[i][2])*((-rp->coord_0.x)-pl[i][2])+((-rp->coord_0.z)-pl[i][0])*((-rp->coord_0.z)-pl[i][0])<rp->rayon*rp->rayon)
{rp->coord_0.x-=p_x; }

if (((-rp->coord_0.x)-pl[i][2])*((-rp->coord_0.x)-pl[i][2])+((-rp->coord_0.z)-pl[i][1])*((-rp->coord_0.z)-pl[i][1])<rp->rayon*rp->rayon)
{rp->coord_0.x-=p_x; }
}
}

if ((rp->collision == 1) || (rp->module_rot>=_1_2EMI_PI && rp->module_rot<_3_2EMI_PI))
for(i=15; i<23; i++) 
if ((-rp->coord_0.z)+rp->rayon>pl[i][2] && (-rp->coord_0.z)-rp->rayon<pl[i][2]) {
if((-rp->coord_0.x)>pl[i][1] && (-rp->coord_0.x)<pl[i][0])
{rp->coord_0.z+=p_z; }

if((-rp->coord_0.x)+rp->rayon>pl[i][1] && (-rp->coord_0.x)-rp->rayon<pl[i][0]) {
if (((-rp->coord_0.z)-pl[i][2])*((-rp->coord_0.z)-pl[i][2])+((-rp->coord_0.x)-pl[i][0])*((-rp->coord_0.x)-pl[i][0])<rp->rayon*rp->rayon)
{rp->coord_0.z+=p_z; }

if (((-rp->coord_0.z)-pl[i][2])*((-rp->coord_0.z)-pl[i][2])+((-rp->coord_0.x)-pl[i][1])*((-rp->coord_0.x)-pl[i][1])<rp->rayon*rp->rayon)
{rp->coord_0.z+=p_z; }
}
}

if ((rp->collision == 1) || (rp->module_rot>=_PI && rp->module_rot<_2PI))
for(i=23; i<30; i++) 
if ((-rp->coord_0.x)+rp->rayon>pl[i][2] && (-rp->coord_0.x)-rp->rayon<pl[i][2]) {
if((-rp->coord_0.z)>pl[i][1] && (-rp->coord_0.z)<pl[i][0])
{rp->coord_0.x-=p_x; }

if((-rp->coord_0.z)+rp->rayon>pl[i][1] && (-rp->coord_0.z)-rp->rayon<pl[i][0]) {
if (((-rp->coord_0.x)-pl[i][2])*((-rp->coord_0.x)-pl[i][2])+((-rp->coord_0.z)-pl[i][0])*((-rp->coord_0.z)-pl[i][0])<rp->rayon*rp->rayon)
{rp->coord_0.x-=p_x; }

if (((-rp->coord_0.x)-pl[i][2])*((-rp->coord_0.x)-pl[i][2])+((-rp->coord_0.z)-pl[i][1])*((-rp->coord_0.z)-pl[i][1])<rp->rayon*rp->rayon)
{rp->coord_0.x-=p_x; }
}
}

Téléchargez la source, cliquez ci-dessous :