Interface 2d½ (style diablo) l'abc (en cours) [visual c++, mfc, sdi]

Description

pour le moment ça ne fait pas grand chose, il y a trois petites fonctions amusantes qui dessine respectivement des murs, des tuiles, ou des murs transparents.

La raison pour laquelle je met immédiatement ce code source ici c'est pour la fonction dessiner_murTransparent. Cette fonction fonctionne à merveille, je n'ai pas à m'en plaindre sauf une chose... elle est vraiement longue à un point où elle est inutilisable... ordinaire un peu non? ALors regardez bien ce qu'elle fait c'est simple et aidez moi à lui donnez un temps d'exécution raisonable.

Pour le reste:
Il est très bien montré comment faire des bitmaps qui n'afficheront pas leur couleur de fond. (les murs et les tuiles ont une couleur mauve pour le fond, pourtant au run-time on ne la voit pas)

Source / Exemple :


/****************************************************************************
//BOOL CFake3DView::PreCreateWindow(CREATESTRUCT& cs)
//
//Fonction: c'est un évènement qui survient à la création de la fenêtre
//je l'ai choisi par défaut comme ça mais le code qui suit doit simplement
//être fait une fois AVANT le premier affichage

                                                                                                                                                          • /
BOOL CFake3DView::PreCreateWindow(CREATESTRUCT& cs) { COLORREF OldBackColor; BITMAP bm; //on charge notre permier bitmap cMur.LoadBitmap(IDB_BITMAP4); //on va chercher ses caractéristiques cMur.GetBitmap(&bm); //on crée un monochrome bitmap de même dimension qiu va contenir le masque cMask_Mur.CreateBitmap(bm.bmWidth,bm.bmHeight,1,1,NULL); //on crée nos device context (on les gardes en passant... pourquoi refaire ce qui est fait) DcPict.CreateCompatibleDC(NULL); DcMask.CreateCompatibleDC(NULL); /****travail de DC******/ //on charge nos images dans nos DC DcPict.SelectObject(&cMur); DcMask.SelectObject(&cMask_Mur); //on change la couleur de fond de notre image et on met la valeur de la couleur //que l'on veut transparente OldBackColor = DcPict.SetBkColor(DcPict.GetPixel(0,0)); //ensuite on copie notre image dans le monochrome bitmap le résultat est: //Pour toute couleur différente de la couleur de fond, la couleur est //noir //pour la couleur = à la couleur de fond, c'est blanc. //donc on se retrouve avec une copie de notre image en noir, un peu comme l'ombre //de notre image DcMask.BitBlt(0,0,bm.bmWidth,bm.bmHeight,&DcPict,0,0,SRCCOPY); //maintenant on fait l'inverse... on va mettre notre masque par dessus notre //image, le but étant que l'on veut mettre au noir tout ce qui ne fait pas //parti de notre image, qui représente le background suivez la recette DcPict.SetTextColor(RGB(255,255,255));//mettre la couleur de texte à blanc DcPict.SetBkColor(RGB(0,0,0));//mettre la couleur de fond à noir //avec l'operation AND, pour tout ce qui a été marqué en blanc dans notre mask //et qui représente le fond, notre image résultante sera marqué de noir //pour le reste, intouché DcPict.BitBlt(0,0,bm.bmWidth,bm.bmHeight,&DcMask,0,0,SRCAND); /****image 2****/ //on fait pareil qu'avec la tuile cTuile.LoadBitmap(IDB_BITMAP3); cTuile.GetBitmap(&bm); //on crée un monochrome bitmap qui va fitter avec cMask_Tuile.CreateBitmap(bm.bmWidth,bm.bmHeight,1,1,NULL); /****travail de DC******/ DcPict.SelectObject(&cTuile); DcMask.SelectObject(&cMask_Tuile); OldBackColor = DcPict.SetBkColor(DcPict.GetPixel(0,0)); DcMask.BitBlt(0,0,bm.bmWidth,bm.bmHeight,&DcPict,0,0,SRCCOPY); DcPict.SetTextColor(RGB(255,255,255)); DcPict.SetBkColor(RGB(0,0,0)); DcPict.BitBlt(0,0,bm.bmWidth,bm.bmHeight,&DcMask,0,0,SRCAND); DcPict.SetBkColor(OldBackColor); return CView::PreCreateWindow(cs); } /**************************************************************************** //void CFake3DView::OnPaint() // //Fonction: C'est un évènement qui survient de temps à autres et qui réclame //un rafraichissement immédiat de la fenêtre. Bon prince nous redessinons //alors la totalité de la fenêtre (pour le moment aucune optimisation de //l'affichage)
                                                                                                                                                          • /
void CFake3DView::OnPaint() { CPaintDC dc(this); // device context for painting //ici c'est le dessinage comme tel.. on a rien a faire alors on en fait un bidon //on verra plus tard quoi faire avec ça Dessiner_Mur(dc,175,190,0); Dessiner_Tuile(dc,150,200,0); Dessiner_Mur(dc,200,200,0); Dessiner_Tuile(dc,175,210,0); Dessiner_Tuile(dc,225,210,0); Dessiner_Tuile(dc,200,220,0); Dessiner_Tuile(dc,125,210,0); Dessiner_Tuile(dc,150,220,0); Dessiner_Tuile(dc,175,230,0); Dessiner_MurTransparent(dc,150,240,0); Dessiner_MurTransparent(dc,200,240,0); Dessiner_MurTransparent(dc,175,250,0); } /**************************************************************************** //void CFake3DView::Dessiner_Mur(CDC &dc,int x,int y,int No_Mur) // //Fonction: Cette méthode a pour fonction de dessiner un mur, les coordonées //x et y qu'elle reçoit en paramètre représente le coin inférieur droit de //l'image (même pas celle du mur puisque qu'une partie est transparente). Celà //vient du fait que nous considèrons le plancher comme étant plat et donc, en //référençant les "éléments graphiques" par le bas on a pas vraiement à //s'occuper de leurs dimensions (ils ont tous la même largeur aussi)
                                                                                                                                                          • /
void CFake3DView::Dessiner_Mur(CDC &dc,int x,int y,int /*No_Mur*/) { BITMAP bm; //on va chercher les dimension de l'image, que l'on va soustraire aux coordonnées //de façon à aligner le bas des images cMur.GetBitmap(&bm); //on commence par dessiner avec un AND notre masque ce qui a pour effet de faire //un gros trou noir qui a la même forme que l'image, (on dessine l'ombre) DcMask.SelectObject(&cMask_Mur); dc.BitBlt(x-bm.bmWidth,y-bm.bmHeight,bm.bmWidth,bm.bmHeight,&DcMask,0,0,SRCAND); //puis avec un OR on dessine ensuite notre image DcPict.SelectObject(&cMur); dc.BitBlt(x-bm.bmWidth,y-bm.bmHeight,bm.bmWidth,bm.bmHeight,&DcPict,0,0,SRCPAINT); } /**************************************************************************** //void CFake3DView::Dessiner_MurTransparent(CDC &dc,int x,int y,int No_Mur) // //Fonction: Cette fonction est amusante, elle dessine le même mur que la //fonction précédente mais elle à la place fait une moyenne entre la couleur //déjà mise à l'écran et la couleur du mur a afficher, ainsi, on a l'impression //de voir au travers du mur, ce qui permet de voir tout le sol, même si nous //sommes derrière un mur
                                                                                                                                                          • /
void CFake3DView::Dessiner_MurTransparent(CDC &dc,int x,int y,int /*No_Mur*/) { BITMAP bm; //on va lire les dimensions comme toujours cMur.GetBitmap(&bm); //on va avoir besoin du masque comme d'habitude DcMask.SelectObject(&cMask_Mur); //on va chercher l'objet à dessiner DcPict.SelectObject(&cMur); //notre matériel de survie int i,j; COLORREF coul_1; COLORREF coul_2; long Result; long Var_temp; //on boucle dans une boucle pour parcourir tout les pixels for(i=x-bm.bmWidth;i<x;i++) { for(j=y-bm.bmHeight;j<y;j++) { //on regarde dans le masque pour savoir si on doit ou non dessiner à cet endroit //(si c'est noir ça veut dire que l'on doit dessiner, sinon (c'est blanc) ça veut dire //que c'est le fond on fait rien if(DcMask.GetPixel(i-(x-bm.bmWidth),j-(y-bm.bmHeight)) == 0) { //on va lire les deux couleurs coul_1 = dc.GetPixel(i,j); coul_2 = DcPict.GetPixel(i-(x-bm.bmWidth),j-(y-bm.bmHeight) ) ; //on fait la moyenne pour les deux valeurs de bleu //j'utilise un ratio 3/4de transparence 1/4 d'opacité donc (3*couleur_1 + couleur_mur) / 4 = couleur_voulue Var_temp = ((coul_1 & 0x00FF0000)+(coul_1 & 0x00FF0000)+(coul_1 & 0x00FF0000)+(coul_2 & 0x00FF0000))/4; Var_temp &= 0x00FF0000; //je masque pour enlever les parties qui ont pu déborder vers la droite Result = Var_temp; //ensuite le vert Var_temp = ((coul_1 & 0x0000FF00)+(coul_1 & 0x0000FF00)+(coul_1 & 0x0000FF00)+(coul_2 & 0x0000FF00))/4; Var_temp &= 0x0000FF00; Result |= Var_temp; //puis le rouge Var_temp = ((coul_1 & 0x000000FF)+(coul_1 & 0x000000FF)+(coul_1 & 0x000000FF)+(coul_2 & 0x000000FF))/4; Var_temp &= 0x000000FF; Result |= Var_temp; //dans le Result on a donc notre couleur selon un ratio de 3/4 dc.SetPixelV(i,j,Result); } } } //fin de la fonction, ce que je recherche donc c'est une fonction qui va faire //exactement ça mais plus rapidement, tout est le bien venu. } /**************************************************************************** //void CFake3DView::OnPaint() // //Fonction:
                                                                                                                                                          • /
void CFake3DView::Dessiner_Tuile(CDC &dc,int x,int y,int /*No_Tuile*/) { BITMAP bm; cTuile.GetBitmap(&bm); //on commence par dessiner notre image en noir DcMask.SelectObject(&cMask_Tuile); dc.BitBlt(x-bm.bmWidth,y-bm.bmHeight,bm.bmWidth,bm.bmHeight,&DcMask,0,0,SRCAND); //puis on dessine avec un OR sur tout ce qui est noir DcPict.SelectObject(&cTuile); dc.BitBlt(x-bm.bmWidth,y-bm.bmHeight,bm.bmWidth,bm.bmHeight,&DcPict,0,0,SRCPAINT); }

Conclusion :


Petit bout de code deviendra grand

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.