C++实现俄罗斯方块

举报
小小谢先生 发表于 2022/04/16 00:51:27 2022/04/16
【摘要】 思路: 画出游戏地图, 并留出下一图形和分数显示的位置图形的建立和颜色图形下落的实现以及上一图形的清除是否能继续下落或变形的检测某一行是否已满需清除以及清除功能与分数更新 核心代码为Run函数 #include<iostream>#include<string>#include<cstdlib>#...

思路:

  1. 画出游戏地图, 并留出下一图形和分数显示的位置
  2. 图形的建立和颜色
  3. 图形下落的实现以及上一图形的清除
  4. 是否能继续下落或变形的检测
  5. 某一行是否已满需清除以及清除功能与分数更新

核心代码为Run函数


  
  1. #include<iostream>
  2. #include<string>
  3. #include<cstdlib>
  4. #include<windows.h>
  5. #include<ctime>
  6. #include<conio.h>
  7. #include<cstdio>
  8. using namespace std;
  9. class Tetris
  10. {
  11. private:
  12. int rank; //游戏难度等级
  13. int score; // 得分
  14. int id; //图形ID
  15. int point[2]; //两基点
  16. int top; //最高点高度
  17. public:
  18. Tetris();
  19. void Welocme(); //首界面
  20. void DrawMap(); //游戏界面
  21. void SetColor(int); //控制颜色
  22. void Draw(int, int, int); //画图形
  23. void Run(); //运行游戏
  24. void ReDraw(int, int, int); //清除图形
  25. bool Judge(int, int, int);
  26. void Turn(int); //旋转
  27. void Updata(); // 更新界面
  28. void Pause(); //游戏暂停
  29. void Input_score();
  30. };
  31. const int sharp[15][8] = //组成图形的各个点的各个坐标,先纵后横
  32. {
  33. {0,0,1,0,2,0,3,0},{0,0,0,1,0,2,0,3},
  34. {0,0,1,0,0,1,1,1},
  35. {0,0,1,0,1,1,1,2},{0,1,1,1,2,0,2,1},{0,0,0,1,0,2,1,2},{0,0,0,1,1,0,2,0},
  36. {1,0,1,1,1,2,0,2},{0,0,0,1,1,1,2,1},{0,0,0,1,0,2,1,0},{0,0,1,0,2,0,2,1},
  37. {0,0,0,1,1,1,1,2},{0,1,1,0,1,1,2,0},
  38. {0,1,0,2,1,0,1,1},{0,0,1,0,1,1,2,1}
  39. };
  40. const int high[15] = { 4,1,2,2,3,2,3,2,3,2,3,2,3,2,3 };
  41. int map[28][16];
  42. #define a1 0 //条形
  43. #define a2 1
  44. #define b 2 // 方块
  45. #define c1 3 //L形
  46. #define c2 4
  47. #define c3 5
  48. #define c4 6
  49. #define d1 7 //T形
  50. #define d2 8
  51. #define d3 9
  52. #define d4 10
  53. #define e1 11 //闪电1形
  54. #define e2 12
  55. #define f1 13 //闪电2形
  56. #define f2 14
  57. Tetris::Tetris() //构造函数, 初始化各个值
  58. {
  59. point[0] = 0;
  60. point[1] = 5;
  61. score = 0;
  62. top = 25;
  63. }
  64. void Tetris::Turn(int num) //旋转函数
  65. {
  66. switch (num)
  67. {
  68. case a1: id = a2; break; //条形互换
  69. case a2: id = a1; break;
  70. case b: id = b; break; //方块无法旋转
  71. case c1: id = c2; break; //各种L形互换
  72. case c2: id = c3; break;
  73. case c3: id = c4; break;
  74. case c4: id = c1; break;
  75. case d1: id = d2; break; //各种T形互换
  76. case d2: id = d3; break;
  77. case d3: id = d4; break;
  78. case d4: id = d1; break;
  79. case e1: id = e2; break; //两种闪电形互换
  80. case e2: id = e1; break;
  81. case f1: id = f2; break;
  82. case f2: id = f1; break;
  83. }
  84. }
  85. void SetPos(int i, int j) //控制光标位置, 列, 行
  86. {
  87. COORD pos = { i,j };
  88. SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
  89. }
  90. void Tetris::Pause() // 暂停函数
  91. {
  92. SetPos(32, 10);
  93. cout << "游戏暂停!" << endl;
  94. SetPos(30, 11);
  95. cout << "你的分数为 " << score;
  96. char temp;
  97. while (1)
  98. {
  99. while (1)
  100. {
  101. if (_kbhit())
  102. {
  103. temp = _getch();
  104. break;
  105. }
  106. }
  107. if (temp == 32)
  108. break;
  109. }
  110. SetPos(32, 10); // 清除暂停时显示的信息
  111. cout << " ";
  112. SetPos(30, 11);
  113. cout << " ";
  114. }
  115. void Tetris::Updata() //更新函数
  116. {
  117. int i, flag;
  118. int nx, ny;
  119. for (i = 0; i < 4; i++)
  120. {
  121. nx = point[0] + sharp[id][i * 2];
  122. ny = point[1] + sharp[id][i * 2 + 1];
  123. SetPos((ny + 1) * 2, nx + 1);
  124. SetColor(0);
  125. cout << "■";
  126. map[nx][ny] = 1; //界面各个点是否为空的更新
  127. }
  128. if (point[0] < top)
  129. top = point[0]; //最高点的更新
  130. for (i = point[0]; i < point[0] + high[id]; i++) //消除行
  131. {
  132. flag = 1;
  133. for (int j = 0; j < 13; j++) //判定某一行是否满, 用flag来标记
  134. if (map[i][j] == 0)
  135. flag = 0;
  136. if (flag == 1)
  137. {
  138. for (int k = i; k >= top; k--)
  139. {
  140. for (int p = 0; p < 13; p++)
  141. {
  142. map[k][p] = map[k - 1][p];
  143. SetPos((p + 1) * 2, k + 1);
  144. if (map[k][p] == 1)
  145. cout << "■";
  146. else cout << " ";
  147. }
  148. }
  149. score += 10;
  150. Input_score();
  151. }
  152. }
  153. }
  154. void Tetris::Input_score()
  155. {
  156. SetColor(3);
  157. SetPos(30, 19);
  158. cout << "得分: " << score;
  159. }
  160. void Tetris::Welocme() //欢迎界面
  161. {
  162. SetColor(1);
  163. char x;
  164. while (1)
  165. {
  166. system("cls");
  167. cout << "■■■■■■■■■■■■■■■■■■■■■" << endl;
  168. cout << " 俄罗斯方块 " << endl;
  169. cout << "■■■■■■■■■■■■■■■■■■■■■" << endl;
  170. cout << " 操作方式:" << endl;
  171. cout << " ↑ - 旋转" << endl;
  172. cout << " ↓ - 加速下移" << endl;
  173. cout << " ← - 左移" << endl;
  174. cout << " → - 右移" << endl;
  175. cout << " 空格 - 暂停" << endl;
  176. cout << "■■■■■■■■■■■■■■■■■■■■■" << endl;
  177. cout << "■ 按1—3选择难度■" << endl;
  178. SetPos(20, 10);
  179. x = getchar();
  180. if (x <= '9' && x >= '0')
  181. {
  182. rank = x - '0';
  183. break;
  184. }
  185. }
  186. }
  187. void Tetris::SetColor(int color_num) //设置颜色
  188. {
  189. int n;
  190. switch (color_num)
  191. {
  192. case 0: n = 0x08; break;
  193. case 1: n = 0x0C; break;
  194. case 2: n = 0x0D; break;
  195. case 3: n = 0x0E; break;
  196. case 4: n = 0x0A; break;
  197. }
  198. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), n);
  199. }
  200. void Tetris::DrawMap() //画游戏时界面
  201. {
  202. int i;
  203. SetColor(0);
  204. for (i = 0; i < 24; i++) //宽24格
  205. {
  206. SetPos(i * 2, 0);
  207. cout << "■";
  208. SetPos(i * 2, 26);
  209. cout << "■";
  210. }
  211. for (i = 0; i < 26; i++) //高26格
  212. {
  213. SetPos(0, i);
  214. cout << "■";
  215. SetPos(28, i);
  216. cout << "■";
  217. SetPos(46, i);
  218. cout << "■";
  219. }
  220. for (i = 14; i < 24; i++)
  221. {
  222. SetPos(i * 2, 16);
  223. cout << "■";
  224. }
  225. SetColor(3);
  226. Input_score();
  227. SetPos(30, 21);
  228. cout << "难度等级: " << rank;
  229. SetPos(32, 2);
  230. cout << "下一图形";
  231. }
  232. void Tetris::Draw(int x, int y, int num) //画图形
  233. {
  234. int nx, ny;
  235. for (int i = 0; i < 4; i++)
  236. {
  237. nx = x + sharp[num][2 * i];
  238. ny = y + sharp[num][2 * i + 1];
  239. SetPos((ny + 1) * 2, nx + 1);
  240. SetColor(i + 1);
  241. cout << "■";
  242. }
  243. }
  244. void Tetris::ReDraw(int x, int y, int num) //为更新图形的位置清除图形
  245. {
  246. int nx, ny;
  247. for (int i = 0; i < 4; i++)
  248. {
  249. nx = x + sharp[num][2 * i];
  250. ny = y + sharp[num][2 * i + 1];
  251. SetPos((ny + 1) * 2, nx + 1);
  252. cout << " ";
  253. }
  254. }
  255. bool Tetris::Judge(int x, int y, int num) //判定在x, y 所指位置是否可画编号为
  256. { //num 的图形, 若不可画则反回true
  257. int nx, ny;
  258. for (int i = 0; i < 4; i++)
  259. {
  260. nx = x + sharp[num][2 * i];
  261. ny = y + sharp[num][2 * i + 1];
  262. if (!(nx < 25 && nx >= 0 && ny < 13 && ny >= 0 && !map[nx][ny]))
  263. return true;
  264. }
  265. return false;
  266. }
  267. void Tetris::Run() //运行游戏
  268. {
  269. int next_id;
  270. srand((int)time(0));
  271. id = rand() % 15;
  272. next_id = rand() % 15;
  273. Draw(point[0], point[1], id);
  274. Draw(5, 16, next_id);
  275. int count;
  276. if (rank == 1)
  277. count = 150;
  278. else if (rank == 2)
  279. count = 100;
  280. else if (rank==3)
  281. count = 50;
  282. else
  283. count = 5;
  284. int i = 0; //不同等级对应不同count
  285. while (1)
  286. {
  287. if (!(i < count)) //i 与 count 用于控制时间
  288. {
  289. i = 0;
  290. if (Judge(point[0] + 1, point[1], id)) //在某一位置不能下落的话
  291. {
  292. Updata();
  293. id = next_id;
  294. ReDraw(5, 16, next_id);
  295. next_id = rand() % 15;
  296. point[0] = 0; point[1] = 5;
  297. Draw(point[0], point[1], id);
  298. Draw(5, 16, next_id);
  299. if (Judge(point[0], point[1], id))
  300. {
  301. system("cls");
  302. SetPos(20, 10);
  303. cout << "游戏结束!" << endl;
  304. SetPos(20, 11);
  305. cout << "你的分数为 " << score << endl;
  306. system("pause");
  307. exit(1);
  308. }
  309. }
  310. else //继续下落
  311. {
  312. ReDraw(point[0], point[1], id);
  313. point[0]++;
  314. Draw(point[0], point[1], id);
  315. }
  316. }
  317. if (_kbhit()) //键盘输入值时
  318. {
  319. int key, key2;
  320. key = _getch();
  321. if (key == 224)
  322. {
  323. key2 = _getch();
  324. if (key2 == 72) //按向上方向键时
  325. {
  326. int temp = id;
  327. Turn(id);
  328. if (Judge(point[0], point[1], id))
  329. id = temp;
  330. ReDraw(point[0], point[1], temp);
  331. Draw(point[0], point[1], id);
  332. }
  333. if (key2 == 80) //按向下方向键时
  334. {
  335. if (!Judge(point[0] + 2, point[1], id))
  336. {
  337. ReDraw(point[0], point[1], id);
  338. point[0] += 2;
  339. Draw(point[0], point[1], id);
  340. }
  341. }
  342. else if (key2 == 75) //按向左方向键时
  343. {
  344. if (!Judge(point[0], point[1] - 1, id))
  345. {
  346. ReDraw(point[0], point[1], id);
  347. point[1]--;
  348. Draw(point[0], point[1], id);
  349. }
  350. }
  351. else if (key2 == 77) //按向右方向键时
  352. {
  353. if (!Judge(point[0], point[1] + 1, id))
  354. {
  355. ReDraw(point[0], point[1], id);
  356. point[1]++;
  357. Draw(point[0], point[1], id);
  358. }
  359. }
  360. }
  361. else if (key == 32) // 按下空格暂停
  362. Pause();
  363. }
  364. Sleep(1); //等待1毫秒
  365. i++; //控制下落间隔
  366. }
  367. }
  368. int main()
  369. {
  370. Tetris game;
  371. game.Welocme();
  372. system("cls"); //清除欢迎界面
  373. game.DrawMap();
  374. game.Run();
  375. }

 

文章来源: blog.csdn.net,作者:小小谢先生,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/xiewenrui1996/article/details/100635192

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。