Tetris main logic


/ Published in: C++
Save to your folder(s)

Кусок самописного тетриса. C++/openGL.


Copy this code and paste it in your HTML
  1. #include "gl.h"
  2. #include <time.h>
  3. #include "Draw.h"
  4. #include "Text.h"
  5.  
  6.  
  7. #include "Game.h"
  8.  
  9. const unsigned char ESC = 27;
  10. const unsigned char SPACE = 32;
  11.  
  12. const unsigned MIN_SPEED = 1;
  13. const unsigned MAX_SPEED = 9;
  14.  
  15. const unsigned BASE_SCORE = 100;
  16. const unsigned NEXT_LEVEL_LINES_LIMIT = 10;
  17.  
  18. Game::Game()
  19. : _lines(0)
  20. , _score(0)
  21. , _speed(MIN_SPEED)
  22. , _lose(false)
  23. , _paused(false)
  24. , _nextFigIndex(rand() % VARIOUS_BLOCKS)
  25. , _nextRotIndex(rand() % ROTATIONS)
  26. {
  27. srand(time(NULL));
  28.  
  29. _well = WellPtr(new Well(this));
  30. _block = BlockPtr(new Block(_well));
  31.  
  32. _StartNextBlock();
  33. }
  34.  
  35. #pragma warning (disable : 4100) //to suppress unused warning int x, int y needed by GLUT API
  36. void Game::KeyPressed(int specialKey, unsigned char key, int x, int y)
  37. {
  38. switch (specialKey)
  39. {
  40. case GLUT_KEY_UP :
  41. case GLUT_KEY_DOWN :
  42. case GLUT_KEY_LEFT :
  43. case GLUT_KEY_RIGHT : _InGameKey(specialKey, 0); break;
  44. }
  45.  
  46. switch (key)
  47. {
  48. case SPACE : _InGameKey(0, key); break;
  49. case '+' : _SpeedUp(); break;
  50. case '-' : _SpeedDown(); break;
  51. case 'p' :
  52. case 'P' : _Pause(); break;
  53. case 'r' :
  54. case 'R' : _Restart(); break;
  55. case ESC : _Stop(); break;
  56. }
  57. }
  58. #pragma warning (default : 4100)
  59.  
  60. void Game::_InGameKey(int specialKey, unsigned char key)
  61. {
  62. if (!_paused && !_lose)
  63. {
  64. switch (specialKey)
  65. {
  66. case GLUT_KEY_UP : _block->Rotate(); break;
  67. case GLUT_KEY_DOWN : _block->MoveDown(); break;
  68. case GLUT_KEY_LEFT : _block->MoveLeft(); break;
  69. case GLUT_KEY_RIGHT : _block->MoveRight(); break;
  70. }
  71.  
  72. switch (key)
  73. {
  74. case SPACE : _block->FallDown();
  75. Update(); break;
  76. }
  77. }
  78. }
  79.  
  80. void Game::Draw()
  81. {
  82. unsigned x0 = 50, y0 = 50, x0new = 0, y0new = 0;
  83.  
  84. glClear(GL_COLOR_BUFFER_BIT);
  85. _DrawWell(x0, y0, x0new, y0new);
  86. _DrawStatus(x0new, y0);
  87.  
  88. glutSwapBuffers();
  89. }
  90.  
  91. void Game::_DrawStatus(unsigned x0, unsigned y0)
  92. {
  93. DrawText(x0, y0 + 20, GLUT_BITMAP_HELVETICA_12, FormatText("Lines: %i", _lines).c_str());
  94. DrawText(x0, y0 + 40, GLUT_BITMAP_HELVETICA_12, FormatText("Score: %i", _score).c_str());
  95. DrawText(x0, y0 + 60, GLUT_BITMAP_HELVETICA_12, FormatText("Speed: %i", _speed).c_str());
  96.  
  97. DrawText(x0, y0 + 420, GLUT_BITMAP_HELVETICA_18, " Next");
  98. _DrawNext(x0, y0 + 460);
  99.  
  100. if (_lose)
  101. {
  102. DrawText(x0, y0 + 240, GLUT_BITMAP_HELVETICA_18, " Game over." );
  103. DrawText(x0, y0 + 220, GLUT_BITMAP_HELVETICA_18, "Press R to restart.");
  104. }
  105. else if (_paused)
  106. {
  107. DrawText(x0, y0 + 240, GLUT_BITMAP_HELVETICA_18, " Game paused." );
  108. DrawText(x0, y0 + 220, GLUT_BITMAP_HELVETICA_18, "Press P to continue.");
  109. }
  110. }
  111.  
  112. void Game::_DrawNext(unsigned x0, unsigned y0)
  113. {
  114. for (unsigned cell = 0; cell != FIGURE_COMPLEXITY; ++cell)
  115. {
  116. unsigned x = x0 + _blocks[_nextFigIndex][_nextRotIndex][2*cell]*_well->CellSize();
  117. unsigned y = y0 + _blocks[_nextFigIndex][_nextRotIndex][2*cell + 1]*_well->CellSize();
  118.  
  119. DrawRect(x, y, x + _well->CellSize(), y + _well->CellSize(), Color[_nextColor - 1]);
  120. }
  121. }
  122.  
  123. void Game::_DrawWell( unsigned x0, unsigned y0, unsigned& x0new, unsigned& y0new )
  124. {
  125. unsigned rectX1 = x0, rectX2 = rectX1 + _well->CellSize();
  126. unsigned rectY1 = y0, rectY2 = rectY1 + _well->CellSize();
  127.  
  128. DrawGrid(x0, y0, _well->Width(), _well->RedLine(), _well->CellSize());
  129. DrawBorder(x0, y0, _well->Width() * _well->CellSize(), _well->Height() * _well->CellSize());
  130.  
  131.  
  132. for (unsigned width = 0; width != _well->Width(); ++width)
  133. {
  134. rectY1 = y0;
  135. rectY2 = rectY1 + _well->CellSize();
  136.  
  137. for (unsigned height = 0; height != _well->Height(); ++height)
  138. {
  139. DrawRect(rectX1, rectY1, rectX2, rectY2, Color[(_well->Cell(width, height) & COLOR_MASK) - 1]);
  140.  
  141. rectY1 = rectY2;
  142. rectY2 += _well->CellSize();
  143. }
  144.  
  145. rectX1 = rectX2;
  146. rectX2 += _well->CellSize();
  147. }
  148.  
  149. x0new = rectX2;
  150. y0new = rectY2;
  151. }
  152.  
  153. void Game::ReportLinesRemoval(unsigned lines)
  154. {
  155. _lines += lines;
  156. _score += lines * BASE_SCORE;
  157.  
  158. while (lines--)
  159. _score += lines * (BASE_SCORE >> lines);
  160. }
  161.  
  162. void Game::_StartNextBlock()
  163. {
  164. _block->Update(_nextFigIndex, _nextRotIndex);
  165.  
  166. _nextFigIndex = rand() % VARIOUS_BLOCKS;
  167. _nextRotIndex = rand() % ROTATIONS;
  168. _nextColor = _nextFigIndex + 1;
  169.  
  170. _block->PutOnTop();
  171. }
  172.  
  173. void Game::Update()
  174. {
  175. if (!_paused && !_block->MoveDown())
  176. {
  177. _block->CheckLines();
  178. if (!_lose)
  179. {
  180. if (_lines >= NEXT_LEVEL_LINES_LIMIT)
  181. {
  182. _SpeedUp();
  183. _lines = 0;
  184. }
  185.  
  186. _StartNextBlock();
  187. }
  188. }
  189. }
  190.  
  191. void Game::_Restart()
  192. {
  193. _lose = false;
  194. _paused = false;
  195. _lines = 0;
  196. _score = 0;
  197.  
  198. _well->Clear();
  199. _StartNextBlock();
  200. }
  201.  
  202. void Game::_Pause()
  203. {
  204. _paused = !_paused;
  205. }
  206.  
  207. void Game::_Stop()
  208. {
  209. exit(0);
  210. }
  211.  
  212. void Game::ReportLoseState()
  213. {
  214. _lose = true;
  215. }
  216.  
  217. unsigned Game::UpdateInterval()
  218. {
  219. return (MAX_SPEED - _speed + 1)*100;
  220. }
  221.  
  222. void Game::_SpeedUp()
  223. {
  224. if (_speed < MAX_SPEED) ++_speed;
  225. }
  226.  
  227. void Game::_SpeedDown()
  228. {
  229. if (_speed > MIN_SPEED) --_speed;
  230. }

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.