|
@@ -0,0 +1,438 @@
|
|
|
+#include "Niveau.h"
|
|
|
+
|
|
|
+Niveau::Niveau():m_font(0),m_items(0),m_nom("Sans Nom"),m_nomFichier(""),m_lvlNumber(0),m_effectifItems(0)
|
|
|
+{
|
|
|
+ m_font = SDL_CreateRGBSurface(SDL_HWSURFACE, 600, 600, 32, 0, 0, 0, 0);
|
|
|
+ m_items = SDL_CreateRGBSurface(SDL_HWSURFACE, 600, 600, 32, 0, 0, 0, 0);
|
|
|
+ reset();
|
|
|
+}
|
|
|
+
|
|
|
+Niveau::Niveau(std::string nomFichier, Uint16 fraction):m_font(0),m_items(0),m_nom("Sans Nom"),m_nomFichier(""),m_lvlNumber(0),m_effectifItems(0)
|
|
|
+{
|
|
|
+ m_font = SDL_CreateRGBSurface(SDL_HWSURFACE, 600, 600, 32, 0, 0, 0, 0);
|
|
|
+ m_items = SDL_CreateRGBSurface(SDL_HWSURFACE, 600, 600, 32, 0, 0, 0, 0);
|
|
|
+
|
|
|
+ if (!creer(nomFichier,fraction))//Si impossible de créer le niveau ...
|
|
|
+ reset();//On le formate. Utile pour l'éditeur, mais impossible à jouer. ;-)
|
|
|
+}
|
|
|
+
|
|
|
+Niveau::~Niveau()
|
|
|
+{
|
|
|
+ SDL_FreeSurface(m_font);
|
|
|
+ SDL_FreeSurface(m_items);
|
|
|
+}
|
|
|
+
|
|
|
+int Niveau::peindreFont(Uint16 fraction)
|
|
|
+{
|
|
|
+ /// [1] Mettre au point les surfaces
|
|
|
+ // [A] Couleur de m_font en rouge + blanc
|
|
|
+ Uint32 fontColor(8388608);//rouge foncé 32 bits
|
|
|
+ SDL_FillRect(m_font,NULL,fontColor);
|
|
|
+ Uint32 blanc(SDL_MapRGB(m_font->format,255,255,255));
|
|
|
+
|
|
|
+ // [B] Surface de colle en rouge et mur_gomme en blanc
|
|
|
+ SDL_Surface* fontCopie = SDL_CreateRGBSurface(SDL_HWSURFACE, m_font->w, m_font->h, 32, 0, 0, 0, 0);
|
|
|
+ SDL_Surface* mur = SDL_CreateRGBSurface(SDL_HWSURFACE, LG_BLOC, LG_BLOC, 32, 0, 0, 0, 0);
|
|
|
+ SDL_FillRect(fontCopie,NULL,fontColor);
|
|
|
+ SDL_FillRect(mur,NULL,blanc);
|
|
|
+ SDL_Rect pos={0,0,0,0};
|
|
|
+
|
|
|
+ // [C] Préparation au gommage
|
|
|
+ if (fraction==0 || LG_BLOC%fraction!=0)
|
|
|
+ {
|
|
|
+ std::cout << "Objet Niveau: argument non renseigné ou non-multiple de " << LG_BLOC << std::endl;
|
|
|
+ fraction=5;
|
|
|
+ }
|
|
|
+ Uint16 coteGum(LG_BLOC/fraction);
|
|
|
+ SDL_Surface* gomme = SDL_CreateRGBSurface(SDL_HWSURFACE,coteGum, coteGum, 32, 0, 0, 0, 0);
|
|
|
+ SDL_FillRect(gomme,NULL,fontColor);
|
|
|
+
|
|
|
+ // [D] Chargement des textures
|
|
|
+ SDL_Surface* solTexture = SDL_LoadBMP("Textures/planks.bmp");
|
|
|
+ SDL_Surface* murTexture = SDL_LoadBMP("Textures/cobblestone.bmp");
|
|
|
+ SDL_Surface* plaqueSprite = SDL_LoadBMP("Textures/plaque.bmp");
|
|
|
+ SDL_Surface* spawnAllieImg = SDL_LoadBMP("Textures/spawnAllie.bmp");
|
|
|
+ SDL_Surface* spawnFantomImg = SDL_LoadBMP("Textures/spawnFantom.bmp");
|
|
|
+ if (solTexture==0 || murTexture==0 || plaqueSprite==0 || spawnAllieImg==0 || spawnFantomImg==0)
|
|
|
+ {
|
|
|
+ std::cout << "Problème de chargement de texture dans l'objet Niveau, dans textures." << std::endl;
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ SDL_SetColorKey(plaqueSprite,SDL_SRCCOLORKEY,blanc);
|
|
|
+ SDL_SetColorKey(spawnAllieImg,SDL_SRCCOLORKEY,blanc);
|
|
|
+ SDL_SetColorKey(spawnFantomImg,SDL_SRCCOLORKEY,blanc);
|
|
|
+
|
|
|
+ // [E] Application des textures
|
|
|
+ SDL_Surface* fullMur = SDL_CreateRGBSurface(SDL_HWSURFACE,600,600, 32, 0, 0, 0, 0);
|
|
|
+ for (int i(0); i<600; i++)
|
|
|
+ {
|
|
|
+ for (int j(0); j<600; j++)
|
|
|
+ {
|
|
|
+ //Collage du sol sur m_font
|
|
|
+ pos.x=i*solTexture->w;
|
|
|
+ pos.y=j*solTexture->h;
|
|
|
+ SDL_BlitSurface(solTexture, 0, m_font, &pos);
|
|
|
+
|
|
|
+ //Collage du mur sur fullMur
|
|
|
+ pos.x=i*murTexture->w;
|
|
|
+ pos.y=j*murTexture->h;
|
|
|
+ SDL_BlitSurface(murTexture, 0, fullMur, &pos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// [2] Dessiner la surface de niveau sur la copie du fond
|
|
|
+ const int largeurTabl(LG_BLOC/coteGum);
|
|
|
+ //Balayage du terrain
|
|
|
+ for (int y(0); y<LG_TABL; y++)
|
|
|
+ {
|
|
|
+ for (int x(0); x<LG_TABL; x++)
|
|
|
+ {
|
|
|
+ //Collage si besoin sur m_font
|
|
|
+ if (m_tabl[y][x]==PLAQUE)
|
|
|
+ {
|
|
|
+ pos.x=x*LG_BLOC+(LG_BLOC-plaqueSprite->w)/2;
|
|
|
+ pos.y=y*LG_BLOC+(LG_BLOC-plaqueSprite->h);
|
|
|
+ SDL_BlitSurface(plaqueSprite,0,m_font,&pos);
|
|
|
+ }
|
|
|
+ if (m_tabl[y][x]==SPAWN_ALLIE)
|
|
|
+ {
|
|
|
+ pos.x=x*LG_BLOC+(LG_BLOC-spawnAllieImg->w)/2;
|
|
|
+ pos.y=y*LG_BLOC+(LG_BLOC-spawnAllieImg->h)/2;
|
|
|
+ SDL_BlitSurface(spawnAllieImg,0,m_font,&pos);
|
|
|
+ }
|
|
|
+ if (m_tabl[y][x]==SPAWN_PHANTOM)
|
|
|
+ {
|
|
|
+ pos.x=x*LG_BLOC+(LG_BLOC-spawnFantomImg->w)/2;
|
|
|
+ pos.y=y*LG_BLOC+(LG_BLOC-spawnFantomImg->h)/2;
|
|
|
+ SDL_BlitSurface(spawnFantomImg,0,m_font,&pos);
|
|
|
+ }
|
|
|
+ //Collage du mur en entier sur fontCopie
|
|
|
+ if (m_tabl[y][x]==MUR)
|
|
|
+ {
|
|
|
+ pos.x=x*LG_BLOC;
|
|
|
+ pos.y=y*LG_BLOC;
|
|
|
+ SDL_BlitSurface(mur, 0, fontCopie, &pos);
|
|
|
+
|
|
|
+ //Ajustement mur
|
|
|
+ for (int i(0); i<largeurTabl; i++)//x
|
|
|
+ {
|
|
|
+ for (int j(0); j<largeurTabl; j++)//y
|
|
|
+ {
|
|
|
+ //Inventaire des parties à conserver
|
|
|
+ short dirx,diry;//permet de savoir où regarder autour
|
|
|
+ if (i==0)
|
|
|
+ dirx=-1;
|
|
|
+ else if (i==largeurTabl-1)
|
|
|
+ dirx=1;
|
|
|
+ else
|
|
|
+ dirx=0;
|
|
|
+ if (j==0)
|
|
|
+ diry=-1;
|
|
|
+ else if (j==largeurTabl-1)
|
|
|
+ diry=1;
|
|
|
+ else
|
|
|
+ diry=0;
|
|
|
+ //Gommage des parties inutiles
|
|
|
+
|
|
|
+ if (typeBloc(x+dirx,y+diry)!=MUR || typeBloc(x+dirx,y)!=MUR || typeBloc(x,y+diry)!=MUR)
|
|
|
+ {
|
|
|
+ pos.x=x*LG_BLOC+i*coteGum;
|
|
|
+ pos.y=y*LG_BLOC+j*coteGum;
|
|
|
+ SDL_BlitSurface(gomme, 0, fontCopie, &pos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }//[END for] Ajustement mur
|
|
|
+ }//[END if] Collage du mur en entier
|
|
|
+ }
|
|
|
+ }//[END for] Balayage du terrain
|
|
|
+
|
|
|
+ /// [3] Finalisation des textures
|
|
|
+ //Mise en place texture des murs
|
|
|
+ SDL_SetColorKey(fontCopie, SDL_SRCCOLORKEY, blanc);//mur en transparence
|
|
|
+ SDL_BlitSurface(fontCopie, 0, fullMur, 0);//colle le tracé du sol sur fullMur
|
|
|
+ SDL_SetColorKey(fullMur,SDL_SRCCOLORKEY,fontColor);//met le sol transparent
|
|
|
+
|
|
|
+ //Coller les murs sur m_font
|
|
|
+ SDL_BlitSurface(fullMur, 0, m_font, 0);
|
|
|
+
|
|
|
+ /// [4] Nettoyer
|
|
|
+ SDL_FreeSurface(murTexture);
|
|
|
+ SDL_FreeSurface(solTexture);
|
|
|
+ SDL_FreeSurface(plaqueSprite);
|
|
|
+ SDL_FreeSurface(mur);
|
|
|
+ SDL_FreeSurface(fontCopie);
|
|
|
+ SDL_FreeSurface(gomme);
|
|
|
+ SDL_FreeSurface(fullMur);
|
|
|
+ SDL_FreeSurface(spawnAllieImg);
|
|
|
+ SDL_FreeSurface(spawnFantomImg);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+bool Niveau::creer(std::string nomFichier, Uint16 fraction)
|
|
|
+{
|
|
|
+ /// [0] Mise au point du nom du fichier
|
|
|
+ nomFichier="Niveaux/"+nomFichier;
|
|
|
+ m_nomFichier=nomFichier;
|
|
|
+
|
|
|
+ /// [1] Ouverture du flux
|
|
|
+ std::ifstream fluxIn(nomFichier.c_str());
|
|
|
+ if (!fluxIn)
|
|
|
+ {
|
|
|
+ std::cout << "Echec de l'ouverture du fichier : "<<nomFichier<<"."<<std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cout << "Ouverture du fichier "<<nomFichier<<" réussie."<<std::endl;
|
|
|
+
|
|
|
+ /// [2] Remplissage du niveau
|
|
|
+ getline(fluxIn,m_nom);
|
|
|
+ fluxIn >> m_lvlNumber;
|
|
|
+ for (int y(0); y<LG_TABL; y++)
|
|
|
+ {
|
|
|
+ for (int x(0); x<LG_TABL; x++)
|
|
|
+ {
|
|
|
+ fluxIn >> m_tabl[y][x];
|
|
|
+ if (m_tabl[y][x] == SPAWN_ALLIE)
|
|
|
+ {
|
|
|
+ m_spawnAllie[Y] = y;
|
|
|
+ m_spawnAllie[X] = x;
|
|
|
+ }
|
|
|
+ else if (m_tabl[y][x] < 0)
|
|
|
+ {
|
|
|
+ m_spawnPhantom[Y] = y;
|
|
|
+ m_spawnPhantom[X] = x;
|
|
|
+ m_effectifMobs = -m_tabl[y][x];
|
|
|
+ m_tabl[y][x] = SPAWN_PHANTOM;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// [3] Peindre la surface du niveau
|
|
|
+ if (peindreFont(fraction)==1)
|
|
|
+ std::cout << "Problème dans la fonction peindreFont() dans niveau." << std::endl;
|
|
|
+
|
|
|
+ /// [4] Mettre les items
|
|
|
+ remplirItems();
|
|
|
+
|
|
|
+ /// [5] Tout va bien !
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+void Niveau::afficher(SDL_Surface* support, bool hideItem)
|
|
|
+{
|
|
|
+ SDL_BlitSurface(m_font, 0, support, 0);
|
|
|
+ if (!hideItem)
|
|
|
+ SDL_BlitSurface(m_items, 0, support, 0);
|
|
|
+}
|
|
|
+
|
|
|
+void Niveau::remplirItems()
|
|
|
+{
|
|
|
+ //Création de la position SDL
|
|
|
+ SDL_Rect pos = {0,0,0,0};
|
|
|
+
|
|
|
+ //Charger les textures
|
|
|
+ SDL_FillRect(m_items,0,0);
|
|
|
+ SDL_Surface* steackImg = SDL_LoadBMP("Textures/steak.bmp");
|
|
|
+ SDL_Surface* tonneauImg = SDL_LoadBMP("Textures/tonneau.bmp");
|
|
|
+ if (steackImg==0 || tonneauImg==0)
|
|
|
+ std::cout << "Problème de chargement de texture dans l'objet Niveau, dans items." << std::endl;
|
|
|
+
|
|
|
+ //Parcours du tableau
|
|
|
+ m_effectifItems=0;
|
|
|
+ for (int x(0); x<LG_TABL; x++)
|
|
|
+ for (int y(0); y<LG_TABL; y++)
|
|
|
+ {
|
|
|
+ //Teste le terrain
|
|
|
+ if (m_tabl[y][x]==RIEN)
|
|
|
+ {
|
|
|
+ //Renseigne la présence du steack
|
|
|
+ m_itemTabl[y][x]=STEACK;
|
|
|
+ m_effectifItems++;
|
|
|
+
|
|
|
+ //Modifie la surface
|
|
|
+ pos.x=x*LG_BLOC+(LG_BLOC-steackImg->w)/2;
|
|
|
+ pos.y=y*LG_BLOC+(LG_BLOC-steackImg->h)/2;
|
|
|
+ SDL_BlitSurface(steackImg, 0, m_items, &pos);
|
|
|
+ }
|
|
|
+ else if (m_tabl[y][x]==PLAQUE)
|
|
|
+ {
|
|
|
+ //Renseignela présence du tonneau
|
|
|
+ m_itemTabl[y][x]=TONNEAU;
|
|
|
+ m_effectifItems++;
|
|
|
+
|
|
|
+ //Modifie la surface
|
|
|
+ pos.x=x*LG_BLOC+(LG_BLOC-tonneauImg->w)/2;
|
|
|
+ pos.y=y*LG_BLOC+(LG_BLOC-tonneauImg->h)/2;
|
|
|
+ SDL_BlitSurface(tonneauImg, 0, m_items, &pos);
|
|
|
+ }
|
|
|
+ else//Renseigne l'absence d'item
|
|
|
+ m_itemTabl[y][x]=VIDE;
|
|
|
+ }
|
|
|
+
|
|
|
+ //Met au point la surface des items
|
|
|
+ SDL_SetColorKey(m_items,SDL_SRCCOLORKEY,0);
|
|
|
+
|
|
|
+ //Nettoyer la texture
|
|
|
+ SDL_FreeSurface(steackImg);
|
|
|
+ SDL_FreeSurface(tonneauImg);
|
|
|
+}
|
|
|
+
|
|
|
+short Niveau::typeBloc(int x, int y, bool coordonee)
|
|
|
+{
|
|
|
+ ///Adapter les coordonnées si besoin
|
|
|
+ if(coordonee)
|
|
|
+ {
|
|
|
+ x /= LG_BLOC;
|
|
|
+ y /= LG_BLOC;
|
|
|
+ }
|
|
|
+ ///Accès sécurisé au tableau
|
|
|
+ if (x<0 || x>=LG_TABL || y>=LG_TABL || y<0)
|
|
|
+ return MUR;
|
|
|
+ else
|
|
|
+ return m_tabl[y][x];
|
|
|
+}
|
|
|
+
|
|
|
+short Niveau::takeItem(int x, int y, bool coordonee)
|
|
|
+{
|
|
|
+ ///Adapter les coordonnées si besoin
|
|
|
+ if(coordonee)
|
|
|
+ {
|
|
|
+ x /= LG_BLOC;
|
|
|
+ y /= LG_BLOC;
|
|
|
+ }
|
|
|
+ ///Accès sécurisé au tableau
|
|
|
+ if (x<0 || x>=LG_TABL || y>=LG_TABL || y<0)
|
|
|
+ {
|
|
|
+ std::cout << "Attention: demande d'une case de tableau inexistante avec typeItem()" << std::endl;
|
|
|
+ return VIDE;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //Recupere l'item
|
|
|
+ short butin(m_itemTabl[y][x]);
|
|
|
+ m_itemTabl[y][x]=VIDE;
|
|
|
+
|
|
|
+ if (butin!=VIDE)
|
|
|
+ {
|
|
|
+ //Gommage de l'item
|
|
|
+ SDL_Surface* gomme = SDL_CreateRGBSurface(SDL_HWSURFACE, LG_BLOC, LG_BLOC, 32, 0, 0, 0, 0);
|
|
|
+ SDL_Rect pos = {0,0,0,0};
|
|
|
+ pos.x=x*LG_BLOC;
|
|
|
+ pos.y=y*LG_BLOC;
|
|
|
+ SDL_BlitSurface(gomme,0,m_items,&pos);
|
|
|
+ SDL_SetColorKey(m_items,SDL_SRCCOLORKEY,0);
|
|
|
+ SDL_FreeSurface(gomme);
|
|
|
+
|
|
|
+ //Retire un objet
|
|
|
+ m_effectifItems--;
|
|
|
+ }
|
|
|
+
|
|
|
+ //Retour
|
|
|
+ return butin;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int Niveau::itemsRestants()
|
|
|
+{
|
|
|
+ return m_effectifItems;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int Niveau::popFantom(axe choisi)
|
|
|
+{
|
|
|
+ if (choisi == X)
|
|
|
+ return m_spawnPhantom[X];
|
|
|
+ else if (choisi == Y)
|
|
|
+ return m_spawnPhantom[Y];
|
|
|
+ else
|
|
|
+ return EXIT_FAILURE;
|
|
|
+}
|
|
|
+
|
|
|
+int Niveau::popAllie(axe choisi)
|
|
|
+{
|
|
|
+ if (choisi == X)
|
|
|
+ return m_spawnAllie[X];
|
|
|
+ else if (choisi == Y)
|
|
|
+ return m_spawnAllie[Y];
|
|
|
+ else
|
|
|
+ return EXIT_FAILURE;
|
|
|
+}
|
|
|
+
|
|
|
+int Niveau::getEffectifMobs()
|
|
|
+{
|
|
|
+ return m_effectifMobs;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+std::string Niveau::getNom()
|
|
|
+{
|
|
|
+ return m_nom;
|
|
|
+}
|
|
|
+
|
|
|
+void Niveau::save(int effectifPhantom)
|
|
|
+{
|
|
|
+ std::cout << "Demande de sauvegarde du niveau: " << m_nomFichier << std::endl;
|
|
|
+ std::ofstream ecriture(m_nomFichier.c_str());
|
|
|
+ if (ecriture)
|
|
|
+ {
|
|
|
+ ecriture << m_nom << std::endl;
|
|
|
+ ecriture << m_lvlNumber;
|
|
|
+ for (int y(0); y<LG_TABL; y++)
|
|
|
+ {
|
|
|
+ ecriture << std::endl;
|
|
|
+ for (int x(0); x<LG_TABL; x++)
|
|
|
+ {
|
|
|
+ if (m_tabl[y][x]==SPAWN_PHANTOM)
|
|
|
+ ecriture << -effectifPhantom;
|
|
|
+ else
|
|
|
+ ecriture << m_tabl[y][x];
|
|
|
+ ecriture << " ";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ std::cout << "La sauvegarde a échoué." << std::endl;
|
|
|
+}
|
|
|
+
|
|
|
+void Niveau::placeBloc(short blocChoisi, int x, int y, Uint32 couleur, bool coordonee)
|
|
|
+{
|
|
|
+ ///Adapter les coordonnées si besoin
|
|
|
+ if(coordonee)
|
|
|
+ {
|
|
|
+ x /= LG_BLOC;
|
|
|
+ y /= LG_BLOC;
|
|
|
+ }
|
|
|
+
|
|
|
+ ///Modifier le tableau numérique
|
|
|
+ if (x>=0 && x<LG_TABL && y>=0 && y<LG_TABL)
|
|
|
+ m_tabl[y][x]=blocChoisi;
|
|
|
+
|
|
|
+ ///Modifier l'image
|
|
|
+ SDL_Surface* carreColore = SDL_CreateRGBSurface(SDL_HWSURFACE, LG_BLOC, LG_BLOC, 32, 0, 0, 0, 0);
|
|
|
+ SDL_FillRect(carreColore,NULL,couleur);
|
|
|
+ SDL_Rect position;
|
|
|
+ position.x = x*LG_BLOC;
|
|
|
+ position.y = y*LG_BLOC;
|
|
|
+ SDL_BlitSurface(carreColore, 0, m_font, &position);
|
|
|
+ SDL_FreeSurface(carreColore);
|
|
|
+}
|
|
|
+
|
|
|
+void Niveau::reset()
|
|
|
+{
|
|
|
+ //Remplir de murs
|
|
|
+ for (int y(0); y<LG_TABL; y++)
|
|
|
+ for (int x(0); x<LG_TABL; x++)
|
|
|
+ m_tabl[y][x]=MUR;
|
|
|
+
|
|
|
+ //Peindre les murs
|
|
|
+ if (peindreFont(5)==1)
|
|
|
+ std::cout << "Problème dans la fonction peindreFont() dans niveau." << std::endl;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|