Chinaunix首页 | 论坛 | 博客
  • 博客访问: 164890
  • 博文数量: 35
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 401
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-28 14:09
文章分类

全部博文(35)

文章存档

2015年(27)

2014年(8)

分类: C/C++

2015-08-02 19:17:02


点击(此处)折叠或打开

  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(int i,int 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.     
  91.     i=15;
  92.     for(i=15;i<=25;i++)
  93.     {
  94.          SetPos(i*2,0);
  95.          cout<<"■";
  96.     }
  97.     for(i=1;i<=8;i++)
  98.     {
  99.         SetPos(15*2,i);
  100.         cout<<"■";
  101.         SetPos(25*2,i);
  102.         cout<<"■";
  103.     }
  104.     for(i=15;i<=25;i++)
  105.     {
  106.          SetPos(i*2,9);
  107.          cout<<"■";
  108.     }

  109.     SetPos(16*2,16);
  110.     cout<<"俄罗斯方块";
  111.     SetPos(16*2,17);
  112.     cout<<"分数:"<<point;
  113.     SetPos(16*2,18);
  114.     cout<<"等级:"<<level;
  115. }

  116. void Box::DrawBox(int x,int y,int num)//绘制图形
  117. {
  118.      int i;
  119.      int nx,ny;
  120.      for(i=0;i<4;i++)
  121.     {
  122.         nx=x+sharp[num][i*2];
  123.         ny=y+sharp[num][i*2+1];
  124.         SetPos((ny+1)*2,nx+1);//利用sharp数组相对于点x,y绘制形状
  125.         cout<<"■";
  126.     }
  127. }

  128. void Box::Redraw(int x,int y,int num)//擦除图形,原理同上
  129. {
  130.      int i;
  131.      int nx,ny;
  132.      for(i=0;i<4;i++)
  133.     {
  134.         nx=x+sharp[num][i*2];
  135.         ny=y+sharp[num][i*2+1];
  136.         SetPos((ny+1)*2,nx+1);
  137.         cout<<" ";
  138.     }
  139. }

  140. void Box::Turn()//转动图形,单纯的该ID而已
  141. {
  142.     switch(ID)
  143.     {
  144.      case A1: ID=A2; break;
  145.      case A2: ID=A1; break;

  146.      case B: ID=B; break;

  147.         case C11: ID=C12; break;
  148.         case C12: ID=C13; break;
  149.         case C13: ID=C14; break;
  150.         case C14: ID=C11; break;

  151.         case C21: ID=C22; break;
  152.         case C22: ID=C23; break;
  153.         case C23: ID=C24; break;
  154.         case C24: ID=C21; break;
  155.         
  156.         case D11: ID=D12; break;
  157.         case D12: ID=D11; break;

  158.         case D21: ID=D22; break;
  159.         case D22: ID=D21; break;
  160.     }

  161. }

  162. void Box::Welcome()//欢迎界面
  163. {
  164.     char x;
  165.     while(1)
  166.     {
  167.      system("cls");
  168.      cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
  169.      cout<<"■ 俄罗斯方块控制台版(不闪屏) ■"<<endl;
  170.      cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
  171.      cout<<"■ A,D左右移动 S向下加速 ■"<<endl;
  172.      cout<<"■ 空格键转动方块 ■"<<endl;
  173.      cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
  174.      cout<<"■ 何某制作 ■"<<endl;
  175.      cout<<"■ 百度ID:HapHapYear ■"<<endl;
  176.      cout<<"■ ■"<<endl;
  177.      cout<<"■ 按1-9选择等级!! ■"<<endl;
  178.      cout<<"■ ■"<<endl;
  179.      cout<<"■ ■"<<endl;
  180.      cout<<"■■■■■■■■■■■■■■■■■■■"<<endl;
  181.      SetPos(8,10);
  182.      x=getch();
  183.      if(x<='9'&&x>='1')//设置等级
  184.      {
  185.          level=x-'0';
  186.          break;
  187.      }
  188.     }
  189. }

  190. void Box::UpdataMap()//更新画面(关键)
  191. {
  192.      int clear;
  193.      int i,j,k;
  194.      int nx,ny;
  195.      int flag;
  196.      for(i=0;i<4;i++)//更新map数组的信息
  197.     {
  198.         nx=hotpoint[0]+sharp[ID][i*2];
  199.         ny=hotpoint[1]+sharp[ID][i*2+1];
  200.         map[nx][ny]=1;
  201.     }
  202.      if(hotpoint[0]<top)//如果热点高于顶点则更新顶点
  203.          top=hotpoint[0];
  204.      clear=0;//消除的格数
  205.      for(i=hotpoint[0];i<hotpoint[0]+high[ID];i++)
  206.      {
  207.          flag=0;
  208.          for(j=0;j<12;j++)//检测是否可以消除此行
  209.          {
  210.              if(map[i][j]==0)
  211.              {
  212.                  flag=1;
  213.                  break;
  214.              }
  215.          }
  216.          if(flag==0)//可以消除
  217.          {
  218.              for(k=i;k>=top;k--)//从当前位置向上所有的点下移一行
  219.              {
  220.                  if(k==0)//最高点特殊处理
  221.                      for(j=0;j<12;j++)
  222.                      {
  223.                          map[k][j]=0;
  224.                          SetPos((j+1)*2,k+1);
  225.                          cout<<" ";
  226.                      }
  227.                  else
  228.                  {
  229.                      for(j=0;j<12;j++)
  230.                      {
  231.                          map[k][j]=map[k-1][j];
  232.                          SetPos((j+1)*2,k+1);
  233.          if(map[k][j]==0)
  234.                          cout<<" ";
  235.                          else
  236.                             cout<<"■";
  237.                      }
  238.                  }

  239.              }
  240.              top++;//消除成功,最高点下移
  241.              clear++;
  242.              point+=clear*100;
  243.          }
  244.      }
  245.        
  246.      SetPos(16*2,17);
  247.      cout<<"分数:"<<point;
  248. }

  249. void Box::Run()//运行游戏
  250. {
  251.     int i=0;
  252.     char x;
  253.     int Count;//计数器
  254.     int tempID;
  255.     int temp;
  256.     srand((int)time(0));
  257.     ID=rand()%15;//随机生成ID和下一个ID
  258.     tempID=rand()%15;
  259.     DrawBox(hotpoint[0],hotpoint[1],ID);//绘制图形
  260.     DrawBox(3,17,tempID);
  261.     Count=1000-level*100;//等级决定计数
  262.     while(1)
  263.     {
  264.         if(i>=Count)//时间到
  265.         {
  266.             i=0;//计数器清零
  267.             if(Judge(hotpoint[0]+1,hotpoint[1]))//如果下个位置无效(即到底)
  268.             {
  269.                  UpdataMap();//更新画面
  270.                  ID=tempID;//生成新ID,用原等待ID替换为当前ID
  271.                  hotpoint[0]=0;//热点更新
  272.                  hotpoint[1]=5;
  273.                  Redraw(3,17,tempID);
  274.                  tempID=rand()%15;
  275.      DrawBox(hotpoint[0],hotpoint[1],ID);
  276.      DrawBox(3,17,tempID);
  277.                  if(Judge(hotpoint[0],hotpoint[1]))//无法绘制开始图形,游戏结束
  278.                  {
  279.                      system("cls");
  280.                      SetPos(25,15);
  281.                      cout<<"游戏结束!!!最终得分为:"<<point<<endl;
  282.                      system("pause");
  283.                      exit(0);
  284.                  }

  285.             }
  286.             else
  287.             {
  288.                 Redraw(hotpoint[0],hotpoint[1],ID);//没有到底,方块下移一位
  289.              hotpoint[0]++;//热点下移
  290.                 DrawBox(hotpoint[0],hotpoint[1],ID);
  291.             }

  292.         }
  293.         if(kbhit())//读取键盘信息
  294.         {
  295.             x=getch();
  296.             if(x=='a'||x=='A')//左移
  297.             {
  298.                  if(Judge(hotpoint[0],hotpoint[1]-1)==0)
  299.                  {
  300.                      Redraw(hotpoint[0],hotpoint[1],ID);
  301.                      hotpoint[1]-=1;
  302.                  DrawBox(hotpoint[0],hotpoint[1],ID);
  303.                  }
  304.             }
  305.             if(x=='d'||x=='D')//右移
  306.             {
  307.              if(Judge(hotpoint[0],hotpoint[1]+1)==0)
  308.                  {
  309.                      Redraw(hotpoint[0],hotpoint[1],ID);
  310.                      hotpoint[1]+=1;
  311.                  DrawBox(hotpoint[0],hotpoint[1],ID);
  312.                  }
  313.             }
  314.             if(x=='s'||x=='S')//向下加速
  315.             {
  316.              if(Judge(hotpoint[0]+1,hotpoint[1])==0)
  317.                  {
  318.                      Redraw(hotpoint[0],hotpoint[1],ID);
  319.                      hotpoint[0]+=1;
  320.                  DrawBox(hotpoint[0],hotpoint[1],ID);
  321.                  }
  322.             }
  323.             if(x==' ')//转动方块
  324.             {
  325.                 temp=ID;
  326.                 Turn();
  327.                 if(Judge(hotpoint[0],hotpoint[1])==0)
  328.                  {
  329.                      Redraw(hotpoint[0],hotpoint[1],temp);
  330.                  DrawBox(hotpoint[0],hotpoint[1],ID);
  331.                  }
  332.                 else
  333.                  ID=temp;
  334.             }
  335.             while(kbhit())//读掉剩下的键盘信息
  336.                 getch();
  337.         }
  338.         Sleep(1);//等待1毫秒
  339.         i++;//计数器加1
  340.     }
  341. }

  342. int Box::Judge(int x,int y)//判断当前是否可以绘制方块
  343. {
  344.     int i;
  345.     int nx,ny;
  346.     for(i=0;i<4;i++)
  347.     {
  348.         nx=x+sharp[ID][i*2];
  349.         ny=y+sharp[ID][i*2+1];
  350.         if(nx<0||nx>=23||ny<0||ny>=12||map[nx][ny]==1)//不能,返回1
  351.             return 1;
  352.     }
  353.     return 0;
  354. }

  355. int main()//主函数
  356. {
  357.     Box game;
  358.     game.Welcome();
  359.     system("cls");
  360.     game.DrawMap();
  361.     game.Run();
  362.     system("pause");
  363. }

阅读(1952) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~