Niveau.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. #include "Niveau.h"
  2. Niveau::Niveau():m_font(0),m_items(0),m_nom("Sans Nom"),m_nomFichier(""),m_lvlNumber(0),m_effectifItems(0)
  3. {
  4. m_font = SDL_CreateRGBSurface(SDL_HWSURFACE, 600, 600, 32, 0, 0, 0, 0);
  5. m_items = SDL_CreateRGBSurface(SDL_HWSURFACE, 600, 600, 32, 0, 0, 0, 0);
  6. reset();
  7. }
  8. 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)
  9. {
  10. m_font = SDL_CreateRGBSurface(SDL_HWSURFACE, 600, 600, 32, 0, 0, 0, 0);
  11. m_items = SDL_CreateRGBSurface(SDL_HWSURFACE, 600, 600, 32, 0, 0, 0, 0);
  12. if (!creer(nomFichier,fraction))//Si impossible de créer le niveau ...
  13. reset();//On le formate. Utile pour l'éditeur, mais impossible à jouer. ;-)
  14. }
  15. Niveau::~Niveau()
  16. {
  17. SDL_FreeSurface(m_font);
  18. SDL_FreeSurface(m_items);
  19. }
  20. int Niveau::peindreFont(Uint16 fraction)
  21. {
  22. /// [1] Mettre au point les surfaces
  23. // [A] Couleur de m_font en rouge + blanc
  24. Uint32 fontColor(8388608);//rouge foncé 32 bits
  25. SDL_FillRect(m_font,NULL,fontColor);
  26. Uint32 blanc(SDL_MapRGB(m_font->format,255,255,255));
  27. // [B] Surface de colle en rouge et mur_gomme en blanc
  28. SDL_Surface* fontCopie = SDL_CreateRGBSurface(SDL_HWSURFACE, m_font->w, m_font->h, 32, 0, 0, 0, 0);
  29. SDL_Surface* mur = SDL_CreateRGBSurface(SDL_HWSURFACE, LG_BLOC, LG_BLOC, 32, 0, 0, 0, 0);
  30. SDL_FillRect(fontCopie,NULL,fontColor);
  31. SDL_FillRect(mur,NULL,blanc);
  32. SDL_Rect pos={0,0,0,0};
  33. // [C] Préparation au gommage
  34. if (fraction==0 || LG_BLOC%fraction!=0)
  35. {
  36. std::cout << "Objet Niveau: argument non renseigné ou non-multiple de " << LG_BLOC << std::endl;
  37. fraction=5;
  38. }
  39. Uint16 coteGum(LG_BLOC/fraction);
  40. SDL_Surface* gomme = SDL_CreateRGBSurface(SDL_HWSURFACE,coteGum, coteGum, 32, 0, 0, 0, 0);
  41. SDL_FillRect(gomme,NULL,fontColor);
  42. // [D] Chargement des textures
  43. SDL_Surface* solTexture = SDL_LoadBMP("Textures/planks.bmp");
  44. SDL_Surface* murTexture = SDL_LoadBMP("Textures/cobblestone.bmp");
  45. SDL_Surface* plaqueSprite = SDL_LoadBMP("Textures/plaque.bmp");
  46. SDL_Surface* spawnAllieImg = SDL_LoadBMP("Textures/spawnAllie.bmp");
  47. SDL_Surface* spawnFantomImg = SDL_LoadBMP("Textures/spawnFantom.bmp");
  48. if (solTexture==0 || murTexture==0 || plaqueSprite==0 || spawnAllieImg==0 || spawnFantomImg==0)
  49. {
  50. std::cout << "Problème de chargement de texture dans l'objet Niveau, dans textures." << std::endl;
  51. return 1;
  52. }
  53. SDL_SetColorKey(plaqueSprite,SDL_SRCCOLORKEY,blanc);
  54. SDL_SetColorKey(spawnAllieImg,SDL_SRCCOLORKEY,blanc);
  55. SDL_SetColorKey(spawnFantomImg,SDL_SRCCOLORKEY,blanc);
  56. // [E] Application des textures
  57. SDL_Surface* fullMur = SDL_CreateRGBSurface(SDL_HWSURFACE,600,600, 32, 0, 0, 0, 0);
  58. for (int i(0); i<600; i++)
  59. {
  60. for (int j(0); j<600; j++)
  61. {
  62. //Collage du sol sur m_font
  63. pos.x=i*solTexture->w;
  64. pos.y=j*solTexture->h;
  65. SDL_BlitSurface(solTexture, 0, m_font, &pos);
  66. //Collage du mur sur fullMur
  67. pos.x=i*murTexture->w;
  68. pos.y=j*murTexture->h;
  69. SDL_BlitSurface(murTexture, 0, fullMur, &pos);
  70. }
  71. }
  72. /// [2] Dessiner la surface de niveau sur la copie du fond
  73. const int largeurTabl(LG_BLOC/coteGum);
  74. //Balayage du terrain
  75. for (int y(0); y<LG_TABL; y++)
  76. {
  77. for (int x(0); x<LG_TABL; x++)
  78. {
  79. //Collage si besoin sur m_font
  80. if (m_tabl[y][x]==PLAQUE)
  81. {
  82. pos.x=x*LG_BLOC+(LG_BLOC-plaqueSprite->w)/2;
  83. pos.y=y*LG_BLOC+(LG_BLOC-plaqueSprite->h);
  84. SDL_BlitSurface(plaqueSprite,0,m_font,&pos);
  85. }
  86. if (m_tabl[y][x]==SPAWN_ALLIE)
  87. {
  88. pos.x=x*LG_BLOC+(LG_BLOC-spawnAllieImg->w)/2;
  89. pos.y=y*LG_BLOC+(LG_BLOC-spawnAllieImg->h)/2;
  90. SDL_BlitSurface(spawnAllieImg,0,m_font,&pos);
  91. }
  92. if (m_tabl[y][x]==SPAWN_PHANTOM)
  93. {
  94. pos.x=x*LG_BLOC+(LG_BLOC-spawnFantomImg->w)/2;
  95. pos.y=y*LG_BLOC+(LG_BLOC-spawnFantomImg->h)/2;
  96. SDL_BlitSurface(spawnFantomImg,0,m_font,&pos);
  97. }
  98. //Collage du mur en entier sur fontCopie
  99. if (m_tabl[y][x]==MUR)
  100. {
  101. pos.x=x*LG_BLOC;
  102. pos.y=y*LG_BLOC;
  103. SDL_BlitSurface(mur, 0, fontCopie, &pos);
  104. //Ajustement mur
  105. for (int i(0); i<largeurTabl; i++)//x
  106. {
  107. for (int j(0); j<largeurTabl; j++)//y
  108. {
  109. //Inventaire des parties à conserver
  110. short dirx,diry;//permet de savoir où regarder autour
  111. if (i==0)
  112. dirx=-1;
  113. else if (i==largeurTabl-1)
  114. dirx=1;
  115. else
  116. dirx=0;
  117. if (j==0)
  118. diry=-1;
  119. else if (j==largeurTabl-1)
  120. diry=1;
  121. else
  122. diry=0;
  123. //Gommage des parties inutiles
  124. if (typeBloc(x+dirx,y+diry)!=MUR || typeBloc(x+dirx,y)!=MUR || typeBloc(x,y+diry)!=MUR)
  125. {
  126. pos.x=x*LG_BLOC+i*coteGum;
  127. pos.y=y*LG_BLOC+j*coteGum;
  128. SDL_BlitSurface(gomme, 0, fontCopie, &pos);
  129. }
  130. }
  131. }//[END for] Ajustement mur
  132. }//[END if] Collage du mur en entier
  133. }
  134. }//[END for] Balayage du terrain
  135. /// [3] Finalisation des textures
  136. //Mise en place texture des murs
  137. SDL_SetColorKey(fontCopie, SDL_SRCCOLORKEY, blanc);//mur en transparence
  138. SDL_BlitSurface(fontCopie, 0, fullMur, 0);//colle le tracé du sol sur fullMur
  139. SDL_SetColorKey(fullMur,SDL_SRCCOLORKEY,fontColor);//met le sol transparent
  140. //Coller les murs sur m_font
  141. SDL_BlitSurface(fullMur, 0, m_font, 0);
  142. /// [4] Nettoyer
  143. SDL_FreeSurface(murTexture);
  144. SDL_FreeSurface(solTexture);
  145. SDL_FreeSurface(plaqueSprite);
  146. SDL_FreeSurface(mur);
  147. SDL_FreeSurface(fontCopie);
  148. SDL_FreeSurface(gomme);
  149. SDL_FreeSurface(fullMur);
  150. SDL_FreeSurface(spawnAllieImg);
  151. SDL_FreeSurface(spawnFantomImg);
  152. return 0;
  153. }
  154. bool Niveau::creer(std::string nomFichier, Uint16 fraction)
  155. {
  156. /// [0] Mise au point du nom du fichier
  157. nomFichier="Niveaux/"+nomFichier;
  158. m_nomFichier=nomFichier;
  159. /// [1] Ouverture du flux
  160. std::ifstream fluxIn(nomFichier.c_str());
  161. if (!fluxIn)
  162. {
  163. std::cout << "Echec de l'ouverture du fichier : "<<nomFichier<<"."<<std::endl;
  164. return false;
  165. }
  166. else
  167. {
  168. std::cout << "Ouverture du fichier "<<nomFichier<<" réussie."<<std::endl;
  169. /// [2] Remplissage du niveau
  170. getline(fluxIn,m_nom);
  171. fluxIn >> m_lvlNumber;
  172. for (int y(0); y<LG_TABL; y++)
  173. {
  174. for (int x(0); x<LG_TABL; x++)
  175. {
  176. fluxIn >> m_tabl[y][x];
  177. if (m_tabl[y][x] == SPAWN_ALLIE)
  178. {
  179. m_spawnAllie[Y] = y;
  180. m_spawnAllie[X] = x;
  181. }
  182. else if (m_tabl[y][x] < 0)
  183. {
  184. m_spawnPhantom[Y] = y;
  185. m_spawnPhantom[X] = x;
  186. m_effectifMobs = -m_tabl[y][x];
  187. m_tabl[y][x] = SPAWN_PHANTOM;
  188. }
  189. }
  190. }
  191. }
  192. /// [3] Peindre la surface du niveau
  193. if (peindreFont(fraction)==1)
  194. std::cout << "Problème dans la fonction peindreFont() dans niveau." << std::endl;
  195. /// [4] Mettre les items
  196. remplirItems();
  197. /// [5] Tout va bien !
  198. return true;
  199. }
  200. void Niveau::afficher(SDL_Surface* support, bool hideItem)
  201. {
  202. SDL_BlitSurface(m_font, 0, support, 0);
  203. if (!hideItem)
  204. SDL_BlitSurface(m_items, 0, support, 0);
  205. }
  206. void Niveau::remplirItems()
  207. {
  208. //Création de la position SDL
  209. SDL_Rect pos = {0,0,0,0};
  210. //Charger les textures
  211. SDL_FillRect(m_items,0,0);
  212. SDL_Surface* steackImg = SDL_LoadBMP("Textures/steak.bmp");
  213. SDL_Surface* tonneauImg = SDL_LoadBMP("Textures/tonneau.bmp");
  214. if (steackImg==0 || tonneauImg==0)
  215. std::cout << "Problème de chargement de texture dans l'objet Niveau, dans items." << std::endl;
  216. //Parcours du tableau
  217. m_effectifItems=0;
  218. for (int x(0); x<LG_TABL; x++)
  219. for (int y(0); y<LG_TABL; y++)
  220. {
  221. //Teste le terrain
  222. if (m_tabl[y][x]==RIEN)
  223. {
  224. //Renseigne la présence du steack
  225. m_itemTabl[y][x]=STEACK;
  226. m_effectifItems++;
  227. //Modifie la surface
  228. pos.x=x*LG_BLOC+(LG_BLOC-steackImg->w)/2;
  229. pos.y=y*LG_BLOC+(LG_BLOC-steackImg->h)/2;
  230. SDL_BlitSurface(steackImg, 0, m_items, &pos);
  231. }
  232. else if (m_tabl[y][x]==PLAQUE)
  233. {
  234. //Renseignela présence du tonneau
  235. m_itemTabl[y][x]=TONNEAU;
  236. m_effectifItems++;
  237. //Modifie la surface
  238. pos.x=x*LG_BLOC+(LG_BLOC-tonneauImg->w)/2;
  239. pos.y=y*LG_BLOC+(LG_BLOC-tonneauImg->h)/2;
  240. SDL_BlitSurface(tonneauImg, 0, m_items, &pos);
  241. }
  242. else//Renseigne l'absence d'item
  243. m_itemTabl[y][x]=VIDE;
  244. }
  245. //Met au point la surface des items
  246. SDL_SetColorKey(m_items,SDL_SRCCOLORKEY,0);
  247. //Nettoyer la texture
  248. SDL_FreeSurface(steackImg);
  249. SDL_FreeSurface(tonneauImg);
  250. }
  251. short Niveau::typeBloc(int x, int y, bool coordonee)
  252. {
  253. ///Adapter les coordonnées si besoin
  254. if(coordonee)
  255. {
  256. x /= LG_BLOC;
  257. y /= LG_BLOC;
  258. }
  259. ///Accès sécurisé au tableau
  260. if (x<0 || x>=LG_TABL || y>=LG_TABL || y<0)
  261. return MUR;
  262. else
  263. return m_tabl[y][x];
  264. }
  265. short Niveau::takeItem(int x, int y, bool coordonee)
  266. {
  267. ///Adapter les coordonnées si besoin
  268. if(coordonee)
  269. {
  270. x /= LG_BLOC;
  271. y /= LG_BLOC;
  272. }
  273. ///Accès sécurisé au tableau
  274. if (x<0 || x>=LG_TABL || y>=LG_TABL || y<0)
  275. {
  276. std::cout << "Attention: demande d'une case de tableau inexistante avec typeItem()" << std::endl;
  277. return VIDE;
  278. }
  279. else
  280. {
  281. //Recupere l'item
  282. short butin(m_itemTabl[y][x]);
  283. m_itemTabl[y][x]=VIDE;
  284. if (butin!=VIDE)
  285. {
  286. //Gommage de l'item
  287. SDL_Surface* gomme = SDL_CreateRGBSurface(SDL_HWSURFACE, LG_BLOC, LG_BLOC, 32, 0, 0, 0, 0);
  288. SDL_Rect pos = {0,0,0,0};
  289. pos.x=x*LG_BLOC;
  290. pos.y=y*LG_BLOC;
  291. SDL_BlitSurface(gomme,0,m_items,&pos);
  292. SDL_SetColorKey(m_items,SDL_SRCCOLORKEY,0);
  293. SDL_FreeSurface(gomme);
  294. //Retire un objet
  295. m_effectifItems--;
  296. }
  297. //Retour
  298. return butin;
  299. }
  300. }
  301. int Niveau::itemsRestants()
  302. {
  303. return m_effectifItems;
  304. }
  305. int Niveau::popFantom(axe choisi)
  306. {
  307. if (choisi == X)
  308. return m_spawnPhantom[X];
  309. else if (choisi == Y)
  310. return m_spawnPhantom[Y];
  311. else
  312. return EXIT_FAILURE;
  313. }
  314. int Niveau::popAllie(axe choisi)
  315. {
  316. if (choisi == X)
  317. return m_spawnAllie[X];
  318. else if (choisi == Y)
  319. return m_spawnAllie[Y];
  320. else
  321. return EXIT_FAILURE;
  322. }
  323. int Niveau::getEffectifMobs()
  324. {
  325. return m_effectifMobs;
  326. }
  327. std::string Niveau::getNom()
  328. {
  329. return m_nom;
  330. }
  331. void Niveau::save(int effectifPhantom)
  332. {
  333. std::cout << "Demande de sauvegarde du niveau: " << m_nomFichier << std::endl;
  334. std::ofstream ecriture(m_nomFichier.c_str());
  335. if (ecriture)
  336. {
  337. ecriture << m_nom << std::endl;
  338. ecriture << m_lvlNumber;
  339. for (int y(0); y<LG_TABL; y++)
  340. {
  341. ecriture << std::endl;
  342. for (int x(0); x<LG_TABL; x++)
  343. {
  344. if (m_tabl[y][x]==SPAWN_PHANTOM)
  345. ecriture << -effectifPhantom;
  346. else
  347. ecriture << m_tabl[y][x];
  348. ecriture << " ";
  349. }
  350. }
  351. }
  352. else
  353. std::cout << "La sauvegarde a échoué." << std::endl;
  354. }
  355. void Niveau::placeBloc(short blocChoisi, int x, int y, Uint32 couleur, bool coordonee)
  356. {
  357. ///Adapter les coordonnées si besoin
  358. if(coordonee)
  359. {
  360. x /= LG_BLOC;
  361. y /= LG_BLOC;
  362. }
  363. ///Modifier le tableau numérique
  364. if (x>=0 && x<LG_TABL && y>=0 && y<LG_TABL)
  365. m_tabl[y][x]=blocChoisi;
  366. ///Modifier l'image
  367. SDL_Surface* carreColore = SDL_CreateRGBSurface(SDL_HWSURFACE, LG_BLOC, LG_BLOC, 32, 0, 0, 0, 0);
  368. SDL_FillRect(carreColore,NULL,couleur);
  369. SDL_Rect position;
  370. position.x = x*LG_BLOC;
  371. position.y = y*LG_BLOC;
  372. SDL_BlitSurface(carreColore, 0, m_font, &position);
  373. SDL_FreeSurface(carreColore);
  374. }
  375. void Niveau::reset()
  376. {
  377. //Remplir de murs
  378. for (int y(0); y<LG_TABL; y++)
  379. for (int x(0); x<LG_TABL; x++)
  380. m_tabl[y][x]=MUR;
  381. //Peindre les murs
  382. if (peindreFont(5)==1)
  383. std::cout << "Problème dans la fonction peindreFont() dans niveau." << std::endl;
  384. }