Les éclairs

Lorsque le module essaie de sortir du plateau, un flux d'éclairs apparaît et le module sans perdre de vies recule automatiquement. Pour créer ce flux d'éclairs nous utilisons le bilboard où l'on applique en boucle une série de textures représentant des éclairs. Ces textures peuvent être dessinées à partir de Photoshop ou de 3DStudio par exemple. Le plus important est d'appliquer un effet Glow sur chaque éclair.

Nous commençons par détecter la collision. Le plateau étant limité par un disque, il est facile de calculer le point d'impact. On relève alors les coordonnées de l'impact, c'est à dire ceux du module puis on joue le son.

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

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

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;

if(rp->coord_0.z * rp->coord_0.z + rp->coord_0.x * rp->coord_0.x > RAYON_LABY) {
rp->collision = 1; rp->rl.x = rp->coord_0.x; rp->rl.y = rp->coord_0.z; rp->rl.rot = rp->module_rot;

DSbuffer[5]->SetCurrentPosition(0); // Met le fichier wav au début
DSbuffer[5]->Play(0,0,0); // Joue le son
rp->stopecl = 1;
}

A ce niveau du tutorial, j'ai restructuré la fonction Rendu en la réduisant à partir de la création de sous fonctions (voir le fichier source). Si stopecl vaut 1, les éclairs doivent être affichés, si il vaut 0, ils ne doivent pas être affichés.

affich_laby(D3DD, rp, mtm_laby);
affich_moduleb(D3DD, rp, rp2, mtm_moduleb);

Missile cell2 = rp2->missile;

affich_missileb(D3DD, rp, rp2, mtm_missile, cell2);

if(rp->collision==1 && rp->stopecl == 1)
affich_eclairs_a(D3DD, pVB, pText, rp);

if(rp2->collision==1 && rp2->stopecl == 1)
affich_eclairs_b(D3DD, pVB, pText, rp, rp2);

billboard_init(D3DD, &(pText[0]), pVB);

affich_hallos(D3DD, rp);

billboard_end(D3DD);

// fin de la scène
(*D3DD)->EndScene();

// affiche le back buffer à l'écran
(*D3DD)->Present(NULL, NULL, NULL, NULL);

Deux nouvelles fonctions sont alors créées : affich_eclairs_a pour les éclairs de notre module et affich_eclairs_b pour les éclairs du module ennemi.

void affich_eclairs_a(LPDIRECT3DDEVICE9 *D3DD, LPDIRECT3DVERTEXBUFFER9 *pVB, LPDIRECT3DTEXTURE9 *pText, _module_ *rp) {

rp->monde._42 = -15.0f;
rp->monde._11 = rp->monde._33 = 1.0f;
rp->monde._13 = rp->monde._31 = 0.0f;

float gx = rp->coord_0.x - rp->rl.x;
float gz = rp->coord_0.z - rp->rl.y;

rp->monde._41=gx*cos(rp->module_rot)+gz*sin(rp->module_rot);
rp->monde._43=-gx*sin(rp->module_rot)+gz*cos(rp->module_rot);

rotation_Y(&rp->monde, rp->module_rot - rp->rl.rot);

billboard_init(D3DD, &(pText[rp->nbr_texture++]), &(pVB[1]));
affich_eclairs(D3DD, rp);
billboard_end(D3DD);

if(rp->nbr_texture > 4)
rp->nbr_texture = 1;

}

void affich_eclairs_b(LPDIRECT3DDEVICE9 *D3DD, LPDIRECT3DVERTEXBUFFER9 *pVB, LPDIRECT3DTEXTURE9 *pText, _module_ *rp, _module_ *rp2) {

rp2->monde._42 = -15.0f;
rp2->monde._11 = rp2->monde._33 = 1.0f;
rp2->monde._13 = rp2->monde._31 = 0.0f;

float vx = rp->coord_0.x - rp2->rl.x;
float vz = rp->coord_0.z - rp2->rl.y;

rp2->monde._41=vx*cos(rp->module_rot)+vz*sin(rp->module_rot);
rp2->monde._43=-vx*sin(rp->module_rot)+vz*cos(rp->module_rot);

rotation_Y(&rp2->monde, rp->module_rot-rp2->rl.rot);

billboard_init(D3DD, &(pText[rp2->nbr_texture]), &(pVB[1]));
affich_eclairs(D3DD, rp2);
billboard_end(D3DD);

}

Dans la fonction main principale on rajoute les paramètres du module :

_module_ *module1 = new _module_;
_module_ *module2 = new _module_;

module1->position_cam.x = 0.0f;
module1->position_cam.y = 0.0f;
module1->position_cam.z = -70.0f;
module1->monde = identite();
module1->rot_cam = 0.0f;
module1->coef_rotation_module = 0.0f;
module1->coef_vitesse_module = 0.0f;
module1->coef_cam = 0.0f;
module1->module_rot = 0.0f;
module1->coord_0.x = 0.0f;
module1->coord_0.y = 0.0f;
module1->coord_0.z = 50.0f;
module1->rayon = 20;
module1->collision = 0;
module1->missile = NULL;
module1->tcr = 0.0f;
module1->nbr_texture = 1;
module1->stopecl = 0;

module2->position_cam.x = 0.0f;
module2->position_cam.y = 0.0f;
module2->position_cam.z = -70.0f;
module2->monde = identite();
module2->rot_cam = 0.0f;
module2->coef_rotation_module = 0.0f;
module2->coef_vitesse_module = 0.0f;
module2->coef_cam = 0.0f;
module2->module_rot = 0.0f;
module2->coord_0.x = 0.0f;
module2->coord_0.y = 0.0f;
module2->coord_0.z = -50.0f;
module2->rayon = 20;
module2->collision = 0;
module2->missile = NULL;
module2->tcr = 0.0f;
module2->nbr_texture = 1;
module2->stopecl = 0;

Ensuite nous chargeons les différentes textures et nous créons une surface pour les éclairs.

char chemin_wav[NBR_SNDS][11] = {"missi.wav", "musik.wav", "impact.wav", "accel.wav", "decel.wav", "elec.wav"};
char chemin_tex[NBR_TEXT][13] = {"glow.bmp", "eclairs1.bmp", "eclairs2.bmp", "eclairs3.bmp", "eclairs4.bmp"};

if(init_DS(hWnd, &obj_DirectSound) != DS_OK)
return -1;

for(i = 0; i < NBR_SNDS; i++)
if(LoadDirectSound(&obj_DirectSound, &(DSbuffer[i]), chemin_wav[i]) != S_OK)
return -1;

for(i = 0; i < NBR_TEXT; i++) {

if(charge_textures(&obj_Direct3DDevice, &(obj_texture[i]), chemin_tex[i]) != S_OK)
return -1;
if(charge_textures(&obj_Direct3DDevice2, &(obj_texture2[i]), chemin_tex[i]) != S_OK)
return -1;
}

if(init_vertices(&obj_Direct3DDevice, &(obj_DirectVB[0]), 20, 20) != S_OK)
return -1;
if(init_vertices(&obj_Direct3DDevice2, &(obj_DirectVB2[0]), 20, 20) != S_OK)
return -1;
if(init_vertices(&obj_Direct3DDevice, &(obj_DirectVB[1]), 100, 100) != S_OK)
return -1;
if(init_vertices(&obj_Direct3DDevice2, &(obj_DirectVB2[1]), 100, 100) != S_OK)
return -1;

dans le ficher principal .h nous avons :

#include <d3d9.h>

#define _PI 3.141592654
#define _2PI 6.283185307
#define _1_2EMI_PI 1.570796327
#define _3_2EMI_PI 4.71238898

#define RAYON_LABY 100000
#define NBR_TEXT 5

static unsigned int long_fenetre, larg_fenetre;
static unsigned int ambiance;

typedef struct _missile_ *Missile;

typedef struct _missile_ {
D3DVECTOR coord;
float t_rot;
Missile suivant, precedent;
} Miss;

struct coord_2D {
float x, y, rot;
};

typedef struct {
D3DMATRIX view_matr;
D3DVECTOR position_cam; 
D3DMATRIX monde;
float rot_cam, coef_rotation_module, coef_vitesse_module, coef_cam, module_rot;
D3DVECTOR coord_0;
Missile missile;
float rayon, tcr;
unsigned char collision,
stopecl;
float vies;

//collision avec l extrémité du labyrinthe
coord_2D rl;
unsigned int nbr_texture;

} _module_;

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