俄罗斯方块(C++)

举报
兔老大 发表于 2021/04/27 23:54:20 2021/04/27
【摘要】 #include<iostream>#include<stdlib.h>#include<windows.h>#include<time.h>#include<conio.h>using namespace std; #define A1 0//A代表长条型,B为方块,C为L型,D为闪电型(实在无法描述那个形状)#d...

  
  1. #include<iostream>
  2. #include<stdlib.h>
  3. #include<windows.h>
  4. #include<time.h>
  5. #include<conio.h>
  6. using namespace std;
  7. #define A1 0//A代表长条型,B为方块,C为L型,D为闪电型(实在无法描述那个形状)
  8. #define A2 1
  9. #define B 2
  10. #define C11 3
  11. #define C12 4
  12. #define C13 5
  13. #define C14 6
  14. #define C21 7
  15. #define C22 8
  16. #define C23 9
  17. #define C24 10
  18. #define D11 11
  19. #define D12 12
  20. #define D21 13
  21. #define D22 14
  22. void SetPos(short i,short j)//设定光标位置
  23. {
  24. COORD pos={i,j};
  25. HANDLE Out=GetStdHandle(STD_OUTPUT_HANDLE);
  26. SetConsoleCursorPosition(Out, pos);
  27. }
  28. int sharp[15][8]=
  29. {
  30. {0,0,1,0,2,0,3,0},{0,0,0,1,0,2,0,3},
  31. {0,0,1,0,0,1,1,1},
  32. {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},
  33. {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},
  34. {0,0,0,1,1,1,1,2},{0,1,1,0,1,1,2,0},
  35. {0,1,0,2,1,0,1,1},{0,0,1,0,1,1,2,1}
  36. };//这个2维数组是用来保存各个形状位置的
  37. int high[15]={4,1,2,2,3,2,3,2,3,2,3,2,3,2,3};//这个数组是用来保存各个形状高度的
  38. class Box//俄罗斯方块类
  39. {
  40. private:
  41. int map[23][12];//画面坐标
  42. int hotpoint[2];//热点(即当前活动的点,所有图形都是相当此点绘制的)
  43. int top;//当前最高位置
  44. int point;//分数
  45. int level;//等级
  46. int ID;//当前活动图形的ID号
  47. public:
  48. Box()//初始化
  49. {
  50. int i,j;
  51. for(i=0;i<23;i++)
  52. for(j=0;j<12;j++)
  53. map[i][j]=0;
  54. hotpoint[0]=0;
  55. hotpoint[1]=5;
  56. point=0;
  57. level=1;
  58. top=99;
  59. ID=0;
  60. }
  61. void DrawMap();//画界面
  62. int Judge(int x,int y);//判断当前位置能否绘制图形
  63. void Welcome();//欢迎界面
  64. void DrawBox(int x,int y,int num);//绘制图形
  65. void Redraw(int x,int y,int num);//擦除图形
  66. void Run();//运行
  67. void Turn();//转动方块
  68. void UpdataMap();//更新画面
  69. };
  70. void Box::DrawMap()//画界面
  71. {
  72. int i;
  73. for(i=0;i<14;i++)
  74. {
  75. SetPos(i*2,0);
  76. cout<<"■";
  77. }
  78. for(i=1;i<=24;i++)
  79. {
  80. SetPos(0,i);
  81. cout<<"■";
  82. SetPos(13*2,i);
  83. cout<<"■";
  84. }
  85. for(i=0;i<14;i++)
  86. {
  87. SetPos(i*2,24);
  88. cout<<"■";
  89. }
  90. i=15;
  91. for(i=15;i<=25;i++)
  92. {
  93. SetPos(i*2,0);
  94. cout<<"■";
  95. }
  96. for(i=1;i<=8;i++)
  97. {
  98. SetPos(15*2,i);
  99. cout<<"■";
  100. SetPos(25*2,i);
  101. cout<<"■";
  102. }
  103. for(i=15;i<=25;i++)
  104. {
  105. SetPos(i*2,9);
  106. cout<<"■";
  107. }
  108. SetPos(16*2,16);
  109. cout<<"俄罗斯方块";
  110. SetPos(16*2,17);
  111. cout<<"分数:"<<point;
  112. SetPos(16*2,18);
  113. cout<<"等级:"<<level;
  114. }
  115. void Box::DrawBox(int x,int y,int num)//绘制图形
  116. {
  117. int i;
  118. int nx,ny;
  119. for(i=0;i<4;i++)
  120. {
  121. nx=x+sharp[num][i*2];
  122. ny=y+sharp[num][i*2+1];
  123. SetPos((ny+1)*2,nx+1);//利用sharp数组相对于点x,y绘制形状
  124. cout<<"■";
  125. }
  126. }
  127. void Box::Redraw(int x,int y,int num)//擦除图形,原理同上
  128. {
  129. int i;
  130. int nx,ny;
  131. for(i=0;i<4;i++)
  132. {
  133. nx=x+sharp[num][i*2];
  134. ny=y+sharp[num][i*2+1];
  135. SetPos((ny+1)*2,nx+1);
  136. cout<<" ";
  137. }
  138. }
  139. void Box::Turn()//转动图形,单纯的该ID而已
  140. {
  141. switch(ID)
  142. {
  143. case A1: ID=A2; break;
  144. case A2: ID=A1; break;
  145. case B: ID=B; break;
  146. case C11: ID=C12; break;
  147. case C12: ID=C13; break;
  148. case C13: ID=C14; break;
  149. case C14: ID=C11; break;
  150. case C21: ID=C22; break;
  151. case C22: ID=C23; break;
  152. case C23: ID=C24; break;
  153. case C24: ID=C21; break;
  154. case D11: ID=D12; break;
  155. case D12: ID=D11; break;
  156. case D21: ID=D22; break;
  157. case D22: ID=D21; break;
  158. }
  159. }
  160. void Box::Welcome()//欢迎界面
  161. {
  162. char x;
  163. while(1)
  164. {
  165. system("cls");
  166. cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
  167. cout<<"■ 俄罗斯方块控制台版(不闪屏) ■"<<endl;
  168. cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
  169. cout<<"■ A,D左右移动 S向下加速 ■"<<endl;
  170. cout<<"■ 空格键转动方块 ■"<<endl;
  171. cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
  172. cout<<"■ ■"<<endl;
  173. cout<<"■ 测试版 ■"<<endl;
  174. cout<<"■ ■"<<endl;
  175. cout<<"■ 按1-9选择等级!! ■"<<endl;
  176. cout<<"■ ■"<<endl;
  177. cout<<"■ ■"<<endl;
  178. cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
  179. SetPos(8,10);
  180. x=getch();
  181. if(x<='9'&&x>='1')//设置等级
  182. {
  183. level=x-'0';
  184. break;
  185. }
  186. }
  187. }
  188. void Box::UpdataMap()//更新画面(关键)
  189. {
  190. int clear;
  191. int i,j,k;
  192. int nx,ny;
  193. int flag;
  194. for(i=0;i<4;i++)//更新map数组的信息
  195. {
  196. nx=hotpoint[0]+sharp[ID][i*2];
  197. ny=hotpoint[1]+sharp[ID][i*2+1];
  198. map[nx][ny]=1;
  199. }
  200. if(hotpoint[0]<top)//如果热点高于顶点则更新顶点
  201. top=hotpoint[0];
  202. clear=0;//消除的格数
  203. for(i=hotpoint[0];i<hotpoint[0]+high[ID];i++)
  204. {
  205. flag=0;
  206. for(j=0;j<12;j++)//检测是否可以消除此行
  207. {
  208. if(map[i][j]==0)
  209. {
  210. flag=1;
  211. break;
  212. }
  213. }
  214. if(flag==0)//可以消除
  215. {
  216. for(k=i;k>=top;k--)//从当前位置向上所有的点下移一行
  217. {
  218. if(k==0)//最高点特殊处理
  219. for(j=0;j<12;j++)
  220. {
  221. map[k][j]=0;
  222. SetPos((j+1)*2,k+1);
  223. cout<<" ";
  224. }
  225. else
  226. {
  227. for(j=0;j<12;j++)
  228. {
  229. map[k][j]=map[k-1][j];
  230. SetPos((j+1)*2,k+1);
  231. if(map[k][j]==0)
  232. cout<<" ";
  233. else
  234. cout<<"■";
  235. }
  236. }
  237. }
  238. top++;//消除成功,最高点下移
  239. clear++;
  240. point+=clear*100;
  241. }
  242. }
  243. SetPos(16*2,17);
  244. cout<<"分数:"<<point;
  245. }
  246. void Box::Run()//运行游戏
  247. {
  248. int i=0;
  249. char x;
  250. int Count;//计数器
  251. int tempID;
  252. int temp;
  253. srand((int)time(0));
  254. ID=rand()%15;//随机生成ID和下一个ID
  255. tempID=rand()%15;
  256. DrawBox(hotpoint[0],hotpoint[1],ID);//绘制图形
  257. DrawBox(3,17,tempID);
  258. Count=1000-level*100;//等级决定计数
  259. while(1)
  260. {
  261. if(i>=Count)//时间到
  262. {
  263. i=0;//计数器清零
  264. if(Judge(hotpoint[0]+1,hotpoint[1]))//如果下个位置无效(即到底)
  265. {
  266. UpdataMap();//更新画面
  267. ID=tempID;//生成新ID,用原等待ID替换为当前ID
  268. hotpoint[0]=0;//热点更新
  269. hotpoint[1]=5;
  270. Redraw(3,17,tempID);
  271. tempID=rand()%15;
  272. DrawBox(hotpoint[0],hotpoint[1],ID);
  273. DrawBox(3,17,tempID);
  274. if(Judge(hotpoint[0],hotpoint[1]))//无法绘制开始图形,游戏结束
  275. {
  276. system("cls");
  277. SetPos(25,15);
  278. cout<<"游戏结束!!!最终得分为:"<<point<<endl;
  279. system("pause");
  280. exit(0);
  281. }
  282. }
  283. else
  284. {
  285. Redraw(hotpoint[0],hotpoint[1],ID);//没有到底,方块下移一位
  286. hotpoint[0]++;//热点下移
  287. DrawBox(hotpoint[0],hotpoint[1],ID);
  288. }
  289. }
  290. if(kbhit())//读取键盘信息
  291. {
  292. x=getch();
  293. if(x=='a'||x=='A')//左移
  294. {
  295. if(Judge(hotpoint[0],hotpoint[1]-1)==0)
  296. {
  297. Redraw(hotpoint[0],hotpoint[1],ID);
  298. hotpoint[1]-=1;
  299. DrawBox(hotpoint[0],hotpoint[1],ID);
  300. }
  301. }
  302. if(x=='d'||x=='D')//右移
  303. {
  304. if(Judge(hotpoint[0],hotpoint[1]+1)==0)
  305. {
  306. Redraw(hotpoint[0],hotpoint[1],ID);
  307. hotpoint[1]+=1;
  308. DrawBox(hotpoint[0],hotpoint[1],ID);
  309. }
  310. }
  311. if(x=='s'||x=='S')//向下加速
  312. {
  313. if(Judge(hotpoint[0]+1,hotpoint[1])==0)
  314. {
  315. Redraw(hotpoint[0],hotpoint[1],ID);
  316. hotpoint[0]+=1;
  317. DrawBox(hotpoint[0],hotpoint[1],ID);
  318. }
  319. }
  320. if(x==' ')//转动方块
  321. {
  322. temp=ID;
  323. Turn();
  324. if(Judge(hotpoint[0],hotpoint[1])==0)
  325. {
  326. Redraw(hotpoint[0],hotpoint[1],temp);
  327. DrawBox(hotpoint[0],hotpoint[1],ID);
  328. }
  329. else
  330. ID=temp;
  331. }
  332. while(kbhit())//读掉剩下的键盘信息
  333. getch();
  334. }
  335. Sleep(1);//等待1毫秒
  336. i++;//计数器加1
  337. }
  338. }
  339. int Box::Judge(int x,int y)//判断当前是否可以绘制方块
  340. {
  341. int i;
  342. int nx,ny;
  343. for(i=0;i<4;i++)
  344. {
  345. nx=x+sharp[ID][i*2];
  346. ny=y+sharp[ID][i*2+1];
  347. if(nx<0||nx>=23||ny<0||ny>=12||map[nx][ny]==1)//不能,返回1
  348. return 1;
  349. }
  350. return 0;
  351. }
  352. int main()//主函数
  353. {
  354. Box game;
  355. game.Welcome();
  356. system("cls");
  357. game.DrawMap();
  358. game.Run();
  359. system("pause");
  360. }

 

文章来源: fantianzuo.blog.csdn.net,作者:兔老大RabbitMQ,版权归原作者所有,如需转载,请联系作者。

原文链接:fantianzuo.blog.csdn.net/article/details/106458006

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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