Niveau.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. #include "Niveau.h"
  2. Niveau::Niveau(SpriteLoader* spriteGet) : m_terrain(0), m_spriteGet(spriteGet)
  3. {
  4. // Surface du terrain
  5. m_terrain = SDL_CreateRGBSurface(SDL_HWSURFACE, 24*40, 18*40, 32, 0, 0, 0, 0);
  6. // Remplissage tableau
  7. for (Uint16 y(0); y < 18; y++)
  8. for (Uint16 x(0); x < 24; x++)
  9. m_tabl[y][x] = '#';
  10. // Association noms aux chars
  11. m_pass['#'] = "mur";
  12. m_pass[' '] = "sol";
  13. m_pass[36] = "end";//'$'
  14. //Association couleurs lettres
  15. Uint32 tab[26] = {0xffff0000, 0xff00ff00, 0x00ffff00, 0xff000000, 0x00ff0000, 0x0000ff00, 0xff770000, 0x00ff7700, 0x7700ff00, 0xff777700, 0x77ff7700, 0x7777ff00, 0x8c551500, 0xff00e000, 0x88880000, 0x88008800, 0x00888800, 0x2cb15800, 0x2cb15800, 0x008ebc00, 0x00bc5400, 0x6fbc0000, 0x6fbc0000, 0xff875200, 0xe56dff00, 0x00000000};
  16. for(int i = 0;i<26;i++)
  17. tabColor[i] = tab[i];
  18. // Création des persos
  19. m_perso[0].skin = m_spriteGet->takeSprite("bleu");
  20. m_perso[1].skin = m_spriteGet->takeSprite("rouge");
  21. m_perso[0].y = m_perso[1].y = 8;
  22. m_perso[0].x = m_perso[1].x = 12;
  23. SDL_SetColorKey(m_perso[0].skin, SDL_SRCCOLORKEY, 0xffffffff);
  24. SDL_SetColorKey(m_perso[1].skin, SDL_SRCCOLORKEY, 0xffffffff);
  25. //Création des
  26. SDL_SetColorKey(m_spriteGet->takeSprite("boutonA"), SDL_SRCCOLORKEY, 0xff000000);
  27. SDL_SetColorKey(m_spriteGet->takeSprite("boutonR"), SDL_SRCCOLORKEY, 0xff000000);
  28. SDL_SetColorKey(m_spriteGet->takeSprite("porteO"), SDL_SRCCOLORKEY, 0xff000000);
  29. SDL_SetColorKey(m_spriteGet->takeSprite("porteF"), SDL_SRCCOLORKEY, 0xff000000);
  30. }
  31. Niveau::~Niveau()
  32. {
  33. SDL_FreeSurface(m_terrain);
  34. }
  35. void Niveau::majLevel(char newTerrain[18][24])
  36. {
  37. // Nettoyage de la map
  38. m_gates.clear();
  39. for(unsigned int y = 0; y<18; y++) for(unsigned int x = 0; x<24; x++) m_caisses[y][x] = false;
  40. // Balayage
  41. for (Uint16 y(0); y < 18; y++)
  42. for (Uint16 x(0); x < 24; x++)
  43. {
  44. // Valeur
  45. m_tabl[y][x] = newTerrain[y][x];
  46. // Pêche aux infos
  47. if (m_tabl[y][x] == '0') {
  48. m_perso[0].y = y;
  49. m_perso[0].x = x;
  50. m_tabl[y][x] = ' ';
  51. }
  52. if (m_tabl[y][x] == '1') {
  53. m_perso[1].y = y;
  54. m_perso[1].x = x;
  55. m_tabl[y][x] = ' ';
  56. }
  57. if(m_tabl[y][x] == '*')
  58. {
  59. m_caisses[y][x] = true;
  60. m_tabl[y][x] = ' ';
  61. }
  62. m_blitPos.x = x*40;
  63. m_blitPos.y = y*40;
  64. if(m_tabl[y][x] >= 97 && m_tabl[y][x] <= 122)//Minuscules
  65. {
  66. m_gates[m_tabl[y][x]].first = false;
  67. m_gates[m_tabl[y][x]].second[0].push_back(x);
  68. m_gates[m_tabl[y][x]].second[0].push_back(y);
  69. SDL_BlitSurface(m_spriteGet->takeSprite(m_pass[' ']), 0, m_terrain, &m_blitPos);
  70. }
  71. else if(m_tabl[y][x] >= 65 && m_tabl[y][x] <= 90)//majuscules
  72. {
  73. m_gates[tolower(m_tabl[y][x])].second[1].push_back(x);
  74. m_gates[tolower(m_tabl[y][x])].second[1].push_back(y);
  75. SDL_BlitSurface(m_spriteGet->takeSprite(m_pass[' ']), 0, m_terrain, &m_blitPos);
  76. }
  77. else //blit si ce n'est ni porte ni bouton
  78. {
  79. SDL_BlitSurface(m_spriteGet->takeSprite(m_pass[m_tabl[y][x]]), 0, m_terrain, &m_blitPos);
  80. }
  81. }
  82. }
  83. void Niveau::afficher(SDL_Surface* screen)
  84. {
  85. // Sol
  86. SDL_BlitSurface(m_terrain, 0, screen, 0);
  87. //affichage des potres/boutons ouvertes/fermées
  88. SDL_Surface *tmpSurface;
  89. for(std::map<char, std::pair<bool, std::vector<int>[2] > >::iterator tmp_gates = m_gates.begin(); tmp_gates!=m_gates.end(); tmp_gates++)
  90. {
  91. int index = (int)tmp_gates->first-97;
  92. //boutons
  93. tmpSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, 40, 40, 32, m_spriteGet->takeSprite("boutonA")->format->Rmask, m_spriteGet->takeSprite("boutonA")->format->Gmask, m_spriteGet->takeSprite("boutonA")->format->Bmask, m_spriteGet->takeSprite("boutonA")->format->Amask);
  94. SDL_FillRect(tmpSurface, 0, tabColor[index]);
  95. if(tmp_gates->second.first)
  96. SDL_BlitSurface(m_spriteGet->takeSprite("boutonA"), 0, tmpSurface, 0);
  97. else
  98. SDL_BlitSurface(m_spriteGet->takeSprite("boutonR"), 0, tmpSurface, 0);
  99. for(unsigned int i = 0;i<tmp_gates->second.second[0].size();i+=2)
  100. {
  101. m_blitPos.x = tmp_gates->second.second[0][i]*40;
  102. m_blitPos.y = tmp_gates->second.second[0][i+1]*40;
  103. SDL_SetColorKey(tmpSurface, SDL_SRCCOLORKEY, 0xffffff00);
  104. SDL_BlitSurface(tmpSurface, 0, screen, &m_blitPos);
  105. }
  106. SDL_FreeSurface(tmpSurface);
  107. //portes
  108. tmpSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, 40, 40, 32, m_spriteGet->takeSprite("porteO")->format->Rmask, m_spriteGet->takeSprite("boutonA")->format->Gmask, m_spriteGet->takeSprite("boutonA")->format->Bmask, m_spriteGet->takeSprite("boutonA")->format->Amask);
  109. SDL_FillRect(tmpSurface, 0, tabColor[index]);
  110. if(tmp_gates->second.first)
  111. SDL_BlitSurface(m_spriteGet->takeSprite("porteO"), 0, tmpSurface, 0);
  112. else
  113. SDL_BlitSurface(m_spriteGet->takeSprite("porteF"), 0, tmpSurface, 0);
  114. for(unsigned int i = 0;i<tmp_gates->second.second[1].size();i+=2)
  115. {
  116. m_blitPos.x = tmp_gates->second.second[1][i]*40;
  117. m_blitPos.y = tmp_gates->second.second[1][i+1]*40;
  118. SDL_SetColorKey(tmpSurface, SDL_SRCCOLORKEY, 0xffffff00);
  119. SDL_BlitSurface(tmpSurface, 0, screen, &m_blitPos);
  120. }
  121. SDL_FreeSurface(tmpSurface);
  122. }
  123. // Caisses
  124. for (Uint16 y(0); y < 18; y++)
  125. for (Uint16 x(0); x < 24; x++)
  126. if (m_caisses[y][x])
  127. {
  128. m_blitPos.x = x*40;
  129. m_blitPos.y = y*40;
  130. SDL_BlitSurface(m_spriteGet->takeSprite("caisse"), 0, screen, &m_blitPos);
  131. }
  132. // Bonhommes
  133. for (Uint16 i(0); i<=1; i++) {
  134. m_blitPos.x = m_perso[i].x*40;
  135. m_blitPos.y = m_perso[i].y*40;
  136. SDL_BlitSurface(m_perso[i].skin, 0, screen, &m_blitPos);
  137. }
  138. }
  139. bool Niveau::test(Uint16 y, Uint16 x, short dirX, short dirY)
  140. {
  141. // Mur ?
  142. if (m_tabl[y][x] == '#')
  143. return false;
  144. // Porte fermée ?
  145. if(m_tabl[y][x] >= 65 && m_tabl[y][x] <= 90)
  146. if (!m_gates[tolower(m_tabl[y][x])].first)
  147. return false;
  148. // Collisions caisse
  149. if (m_caisses[y][x]) {
  150. if(m_tabl[y+dirY][x+dirX] == '#')
  151. return false;
  152. if(m_tabl[y+dirY][x+dirX] >= 65 && m_tabl[y+dirY][x+dirX] <= 90)
  153. {
  154. if(m_gates[tolower(m_tabl[y+dirY][x+dirX])].first)
  155. {
  156. m_caisses[y][x] = false;
  157. m_caisses[y + dirY][x + dirX] = true;
  158. return true;
  159. }
  160. else
  161. return false;
  162. }
  163. else
  164. {
  165. m_caisses[y][x] = false;
  166. m_caisses[y + dirY][x + dirX] = true;
  167. return true;
  168. }
  169. }
  170. // Si rien n'empêche ...
  171. return true;
  172. }
  173. char Niveau::getCase(Uint16 y, Uint16 x)
  174. {
  175. if (y < 18 && x < 24)
  176. return m_tabl[y][x];
  177. return '#';
  178. }
  179. void Niveau::setCase(Uint16 y, Uint16 x, char bloc)
  180. {
  181. if (y < 18 && x < 24)
  182. m_tabl[y][x] = bloc;
  183. }
  184. bool Niveau::deplacer(char ID, char ordre)
  185. {
  186. // Détermination du joueur qui bouge
  187. Uint16 ind;
  188. if (ID == '0') ind = 0;
  189. else ind = 1;
  190. // Détermination de la direction
  191. short dirX(0), dirY(0);
  192. switch (ordre)
  193. {
  194. case 24://'↑'
  195. dirY--;
  196. break;
  197. case 25://'↓'
  198. dirY++;
  199. break;
  200. case 26://'→'
  201. dirX++;
  202. break;
  203. case 27://'←'
  204. dirX--;
  205. break;
  206. default:
  207. break;
  208. }
  209. // Collisions bonhomme
  210. for(std::map<char, std::pair<bool, std::vector<int>[2] > >::iterator tmp_gates = m_gates.begin(); tmp_gates!=m_gates.end(); tmp_gates++)
  211. for(unsigned int i = 0;i<tmp_gates->second.second[1].size();i+=2)
  212. if(tmp_gates->second.second[1][i] == m_perso[ind].x && tmp_gates->second.second[1][i+1] == m_perso[ind].y)
  213. {
  214. if(tmp_gates->second.first)
  215. break;
  216. else
  217. return false;
  218. }
  219. if (test(m_perso[ind].y+dirY, m_perso[ind].x+dirX, dirX, dirY)) {
  220. m_perso[ind].y += dirY;
  221. m_perso[ind].x += dirX;
  222. }
  223. return true;
  224. }
  225. void Niveau::updateBoutons()
  226. {
  227. // Vérifie si un bouton est activé par une caisse A BOUGER
  228. for(std::map<char, std::pair<bool, std::vector<int>[2] > >::iterator tmp_gates = m_gates.begin(); tmp_gates!=m_gates.end(); tmp_gates++)
  229. {
  230. tmp_gates->second.first = false;
  231. for(unsigned int i = 0;i<tmp_gates->second.second[0].size();i+=2)
  232. tmp_gates->second.first |= m_caisses[tmp_gates->second.second[0][i+1]][tmp_gates->second.second[0][i]];
  233. }
  234. // Vérifie perso on bouton
  235. int x, y;
  236. for (Uint16 i(0); i<=1; i++) {
  237. x = m_perso[i].x;
  238. y = m_perso[i].y;
  239. if(m_tabl[y][x] >= 97 && m_tabl[y][x] <= 122)
  240. m_gates[m_tabl[y][x]].first = true;
  241. }
  242. //destruction si caisse sur porte fermée
  243. for(std::map<char, std::pair<bool, std::vector<int>[2] > >::iterator tmp_gates = m_gates.begin(); tmp_gates!=m_gates.end(); tmp_gates++)
  244. for(unsigned int i = 0;i<tmp_gates->second.second[1].size();i+=2)
  245. if(!tmp_gates->second.first && m_caisses[tmp_gates->second.second[1][i+1]][tmp_gates->second.second[1][i]])
  246. m_caisses[tmp_gates->second.second[1][i+1]][tmp_gates->second.second[1][i]] = false;
  247. }
  248. bool Niveau::suisJeArrive(char ID)
  249. {
  250. // Détermination du joueur qui bouge
  251. Uint16 ind;
  252. if (ID == '0') ind = 0;
  253. else ind = 1;
  254. // Retour
  255. return (m_tabl[m_perso[ind].y][m_perso[ind].x] == 36);//'$'
  256. }