准新手 c++ win32 API实现方块联机游戏历程

                写俄罗斯方块联机游戏想法,源于到北京后的培训经历,那时候的老师是一个在华为经历几年开发经验和测试经验的高手,当他告诉我说:“听说你号称学过C++的时候”。也开始有想用C++写个小东西的想法。直到最近终于付诸于现实。

        大学时间学习了MFC,对WINDOWS窗口的运行机制一窍不通,只会拖拖控件添加消息,是个准新手。于是开始看一些关于那方面的书和视频,主要是 《Windows程序设计》和孙鑫的c++视频第一、二章节。了解面向对象的基本概念和WINDWOS窗口的消息机制等基本的理论。有了这些基础后,大概就有个模型,觉得可以实现这个俄罗斯方块游戏。开始实际写代码。

        所有复杂的东西都是由最简单的东西组成的,我所有的编程思路和实现都是基于这个简单的思路来做的。当然这个游戏很简单,对于一些有经验的朋友可以说是 一天半天就可以完成的,但是对于完全没有windwos窗口编程的新手来说,这会是一个让人务实,让人探索前进的思路。我坚信在开发进行中的所有困难或BUG都是因为一个很简单的错误而出现的。我能做的就是不停的实验和测试来实现。在这方面,测试的经验给了我不少的帮助。让我在出现问题的时候,有大量的想法去测试寻找问题的缘由,+上自己的耐心,所有的问题都迎刃而解。

准新手 c++ win32 API实现方块联机游戏历程_第1张图片

实际过程:

      

       1 对话框: 最开始,什么都不想,要玩游戏就得有个窗口。我用createwindow把里面大部分的窗口类型都组合测试了一边,最终才选定用一个没有最大化最小化按钮、没有改变大小边框的对话框窗口来实现。

  

        2 游戏界面:用什么实现方块。有很多想法,用一张画好的图片,做方块格子,也想过用按钮。最后想想就用一个彩色矩形代表一个方块最简单。FillRect();

  

      3 游戏方块: 接着用设计好游戏规格,方块大小,游戏界面宽高。就用FillRect()画个黑色矩形来表示游戏方块。现在想想其实建立一个子窗口做界面是最方便的了 。

 

       4 显示第一个方块:游戏对话框有了,游戏界面有了,于是我试着在黑色矩形游戏界面中画第一个方块,是一个直条。这也是我第一次接触到WM_PAINT消息。第一次知道窗口的重绘。刚开始的时候,出现很多的问题,不是只有直条就是只有游戏界面。在重绘函数里面有很多错误的代码,走了很多湾路。光为了在游戏界面中画出一个直条我就画了两天,终于才明白重绘的原理和基本的函数的使用。当我在游戏界面中出现第一个直条的时候,我非常兴奋,我觉得这个是一个很好的开始,起码证明了我的方法在一定程度上是可行的。意味着前面的工作都没白费。给了我很大的鼓舞。

 

       5 设计方块基类: 有了前面的基础,我就坚信可以完成。我觉得方块基类是整个游戏的基础, 一定要先确定好的,于是设计了一个4维的数组来表达7类方块20多种的变化。这样在游戏中需要方块的数据的时候都可以从中提取。其实最开始的时候在这块想了很多,因为不确定后面到底要怎么样用到方块,承前启后的想了很久,既要考虑到后面的使用,又要尽量简单,最开始的时候还想用vector来实现,于是还顺便学习了关于容器的内容,怎么使用怎么初始化等等。不过最后还是否定了这个方案。

 

 

      6  设计游戏类:其实不懂面向对象,只是觉得,不同类型的要分块。你只管提供数据,我只管操作。于是就设计了游戏类。

当时也不知道游戏类里面到底需要什么方法,只是觉得有些方法是必须要的。比如 移动 下降 消行 游戏开始 游戏结束 游戏暂停等。也不想那么多,一股脑的都+上。

 

      7  游戏运行机制:是游戏就要有开始,就要有结束,要有运行。看别人的代码都写的很好,一个死循环就可以让游戏不停运行。我想往上套,始终也不行。只能另想办法。最后因为方块游戏的运行就是下降。所以我只要弄一个函数不停的调用下降,就能实现游戏运行的原理。至于什么时候下降停止。那可以具体再写。我觉得这样是对的。最终找到了SETTIMMER来实现

 

       8  游戏算法实现:当我第一次看到,随机生成的方块,在游戏界面里缓缓下降的时候。。。 我心里那个美啊。。 我知道我对了,胜利在望了。接下的东西就是具体的游戏功能的写作,一切都顺利了许多,我只是不停的测试+写+测试。完成。在写完之前我开始想着,下一步的实现。网络版

 

      9   单机游戏完成: 所有的都完成,单机游戏终于完成后,自己也是不停的测试,优化算法,这中间还出现内存泄露的严重问题,也因祸得福了解了内存的基本使用。直到修复问题。最终单机版的无bug版完成。我中间公司的项目也多了老加班,就先放下了。

    

      10  网络版的孕育: 07年同学在武汉,有个朋友介绍他去干开发的工作。那边的人说了,在一个月之内,如果开发出一个网络版的俄罗斯方块游戏,那么OK,来上班。我想起这见事情,于是我想着能否实现它。其实这还是做一个测试的一个心结。自己也有心思转开发,所以决定去实现这个。

 

      11  网络版的实现过程: 因为整个游戏只有两个类,所有我觉得给网络功能这块+一个类。所有的网络功能都在那里实现,在开发的过程中发现,由于没有很好的设计,导致在实现的时候出现很多的矛盾。从而我也认识到设计和算法在软件开发中的重要性。跌跌撞撞的用WIndows socket使用UDP的协议实现了联机通讯,中间专门先实验几个通讯小例子,再把觉得可用的代码用上,现在基本的联机功能都以实现。很想模仿腾讯QQ火拼俄罗斯游戏开发游戏道具。但目前也只停留在想的阶段。

    .

       游戏介绍:

         1  单机版和网络版并存

         2  网络版:实现在线用户实时状态显示,(空闲中 游戏中 离线)

         3  网络版:邀请对方联机对战。若对方状态不可以邀请,则不能邀请

         4  网络版:双人联机对战实现,可以看到对方实时的方块数据。游戏胜负根据率先到达10000分的一方获胜

         5  网络版道具使用: 酝酿中。。。。。。。

 

        结束语: 第一个C++ WIN232的程序,虽然只是个小游戏,但也给了我一些信心和鼓舞,希望有机会能正式加入程序员阵营中来,目前职位还是测试工作,想这下一步的开发方向该怎么走。希望各位同仁多多指教,给点建议。多谢啦。

    
       下载地址:http://download.csdn.net/source/727355

       部分源码:

Gameframe.h

 

  1. #include "GameNet.h"
  2. #ifndef _GAMEFRAME_H_
  3. #define _GAMEFRAME_H_
  4. using namespace std;
  5. #define SingleRect 30                     //单个方块大小
  6. #define FRAME_L 15                         //主界面的起点坐标 L
  7. #define FRAME_T 15                        //主界面的起点坐标 T
  8. #define NEXT_L   SingleRect*10+FRAME_L+15    //下一个方块的起点座标 L
  9. #define NEXT_T   FRAME_T                     //下一个方块的起点座标 T
  10. #define MAIN_SIZE_R SingleRect*10+FRAME_L       //主界面x_x
  11. #define MAIN_SIZE_B SingleRect*20+FRAME_T       //主界面y_y
  12. #define NEXT_SIZE_R SingleRect*4+NEXT_L+20   //下一个方块x_x
  13. #define NEXT_SIZE_B SingleRect*4+NEXT_T+20   //下一个方块y_y
  14. class Gameframe:public GameNet
  15. {
  16. public:
  17.     Gameframe();
  18.     virtual ~Gameframe();
  19.     void Draw_Frame(HDC hDC,HWND hwnd,HBRUSH G_brush);//重绘主框架
  20.     void Draw_Next(HDC hDC,HWND hwnd,HBRUSH G_brush);重绘下一个方块框架
  21.     void Draw_Message(HDC hDC,HWND hwnd,HBRUSH G_brush);//重绘下一个方块框架
  22.     void Draw_Child(HDC hDC,HWND hwnd,HBRUSH G_brush);//重绘子窗口
  23.     void Game_Start();//开始游戏
  24.     bool G_Stop;//游戏是否暂停
  25.     bool Game_Over();//判断游戏是否结束
  26.     void Game_Run();//开始运行,设定下落时间
  27.     void Game_Down();//方块下落
  28.     void Game_Change();//方块变形
  29.     bool Game_Move(int i);//方块移动
  30.     void Game_Stop();
  31.     void Game_Restart();
  32.     void Game_Sound(unsigned short int sound);
  33.     bool Down_end;
  34.     bool Space_on;
  35.     char G_Path[100];//游戏路径
  36. protected:
  37.     void Next_Rand();//生成下一个方块
  38.     RECT N;//下一个方块界面
  39.     RECT F;//主界面
  40.     RECT Active_Rect;//方块活动界面
  41.     RECT Total;//得分界面
  42.     RECT re;//
  43.     unsigned short int Actvie_bottom;//活动方块的最下面
  44.     Square squ;//定义一个方块的对象
  45.     short int Next_A;//下一个方块类型
  46.     short int Next_B;//下一个方块具体形状
  47.     short int Frame_A;//当前方块类型
  48.     short int Frame_B;//当前方块具体形状
  49.     short int Move;//移动格子数
  50.     short int Down;//下降个数
  51.     short int Now_Cake[4][2];//新方块 0横坐标 1纵坐标
  52.     short int Old_Cake[4][2];//旧方块 0横坐标 1纵坐标
  53.     short int Top;//有方块的最高点
  54.     bool Gframe[10][20];//10横坐标  20 纵坐标
  55.     unsigned short int G_Level;
  56.     int Rect_Falling;    //下落时间差
  57.     short int Gframe_Color[10][20];//主游戏方块颜色
  58.     short int Rect_Color;//当前方块颜色
  59.     short int Rect_Color_N;//下一个方块颜色
  60.     COLORREF G_BasicColor[7];//方块颜色基础
  61.     bool Game_Active(int Event);//方块事件处理
  62.     bool Game_DelRect();//消行算法
  63. private:
  64. };
  65. #endif

 Gamefrme.cpp

  1. #include "Gameframe.h"
  2. //
  3. // Gameframe Class
  4. //
  5. int Move_temp;
  6. extern HINSTANCE h_inst;
  7. extern HWND hwnd;
  8. extern HWND U_hwnd;//用户列表
  9. void Gameframe::Draw_Next(HDC hDC,HWND hwnd,HBRUSH G_brush)// 重绘下一个方块框架主游戏框架+内容
  10. {
  11.     N.left=Total.left;
  12.     FillRect(hDC,&N,G_brush);
  13.     FillRect(hDC,&Total,G_brush);
  14.     
  15.     SetDCBrushColor(hDC,G_BasicColor[Rect_Color_N]);
  16.     for(int c=0;c<4;c++)
  17.     {
  18.         for(int d=0;d<4;d++)
  19.         {
  20.             if(1==squ.Nextframe[Next_A][Next_B][d][c])
  21.             {
  22.                 SetRect(&re,NEXT_L+c*30+1+10,NEXT_T+d*30+1+10,NEXT_L+c*30+29+10,NEXT_T+d*30+29+10);
  23.                 FillRect(hDC,&re,G_brush);
  24.             }
  25.         }
  26.     }
  27.     char szChar[25];
  28.     sprintf(szChar,"%d   VS   %d",Game_Point,Child_Point);
  29.     unsigned short int count=0,i=0;
  30.     while(szChar[i] != '/0')
  31.     { 
  32.         count++; 
  33.         i++; 
  34.     }
  35.     TextOut(hDC,NEXT_L+20,NEXT_T+185,szChar,count);
  36. }
  37. void Gameframe::Draw_Frame(HDC hDC,HWND hwnd,HBRUSH G_brush)//主游戏框架+内容
  38. {
  39.     SetDCBrushColor(hDC,RGB(0,0,0));
  40.     FillRect(hDC,&F,G_brush);
  41.     for(unsigned short int o=0;o<10;o++)
  42.     {
  43.         for(unsigned short int p=0;p<20;p++)
  44.         {
  45.             if(1==Gframe[o][p])
  46.             {
  47.                 SetDCBrushColor(hDC,G_BasicColor[Gframe_Color[o][p]]);
  48.                 SetRect(&re,FRAME_L+o*30+1,FRAME_T+p*30+1,FRAME_L+o*30+29,FRAME_T+p*30+29);
  49.                 FillRect(hDC,&re,G_brush);
  50.             }
  51.         }
  52.     }
  53.     if(G_Over)
  54.     {
  55.        if(G_Level>9)
  56.        {
  57.            G_Level=1;
  58.            TextOut(hDC,FRAME_L+100,FRAME_T+270,"通关了!厉害",strlen("            "));
  59.        }
  60.        else
  61.        {
  62.            if(!Arrive)
  63.            {
  64.                TextOut(hDC,FRAME_L+100,FRAME_T+270,"GAME OVER",strlen("GAME OVER"));
  65.            }
  66.            else
  67.            {
  68.                TextOut(hDC,FRAME_L+100,FRAME_T+270,"YOU'RE WINNER",strlen("YOU'RE WINNER"));
  69.            }
  70.        }
  71.     }
  72. }
  73. void Gameframe::Draw_Message(HDC hDC,HWND hwnd,HBRUSH G_brush)
  74. {
  75.     SetDCBrushColor(hDC,RGB(255,255,255));
  76.     SetTextColor(hDC,RGB(0,0,0));
  77.     FillRect(hDC,&Info,G_brush);
  78.     DrawText(hDC,InfoChar,strlen(InfoChar),&Info,DT_LEFT);
  79. }
  80. void Gameframe::Draw_Child(HDC hDC,HWND hwnd,HBRUSH G_brush)
  81. {
  82.     SetDCBrushColor(hDC,RGB(0,0,0));
  83.     SetRect(&re,0,0,200,400);
  84.     FillRect(hDC,&re,G_brush);
  85.     for(unsigned short int o=0;o<10;o++)
  86.     {
  87.         for(unsigned short int p=0;p<20;p++)
  88.         {
  89.             if(0!=Child_Frame[o][p])
  90.             {
  91.                 SetDCBrushColor(hDC,G_BasicColor[Child_Frame[o][p]-1]);
  92.                 SetRect(&re,o*20+1,p*20+1,o*20+19,p*20+19);
  93.                 FillRect(hDC,&re,G_brush);
  94.             }
  95.         }
  96.     }
  97. }
  98. Gameframe::Gameframe()
  99. {
  100.     //主游戏框初始化
  101.     SetRect(&F,FRAME_L,FRAME_T,MAIN_SIZE_R,MAIN_SIZE_B);
  102.     SetRect(&N,NEXT_L,NEXT_T,NEXT_SIZE_R,NEXT_SIZE_B);//下一个框
  103.     SetRect(&Total,NEXT_L,NEXT_T+170,NEXT_SIZE_R,NEXT_SIZE_B+80);//得分框
  104.     SetRect(&Info,NEXT_SIZE_R+FRAME_L+FRAME_L,FRAME_T+400+20,NEXT_SIZE_R+FRAME_L+FRAME_L+200,FRAME_T+400+20+100);//消息框
  105.    
  106.     G_BasicColor[0] = RGB(220, 39, 75);     // 红
  107.     G_BasicColor[1] = RGB(232, 123, 20);    // 橙
  108.     G_BasicColor[2] = RGB(200, 200, 102);   // 黄
  109.     G_BasicColor[3] = RGB(51, 204, 102);    // 绿
  110.     G_BasicColor[4] = RGB(0, 143, 224);     // 蓝
  111.     G_BasicColor[5] = RGB(153, 153, 204);   // 青
  112.     G_BasicColor[6] = RGB(204, 204, 204);   // 灰
  113.     
  114.     getcwd(G_Path,80);
  115.     strcat(G_Path,"//resource//Wav//");//获得资源路径
  116.     G_NET=false;
  117.     this->Game_Restart();
  118. }
  119. Gameframe::~Gameframe()
  120. {
  121.     squ.~Square();
  122. }
  123. void Gameframe::Game_Start()
  124. {
  125.     //游戏开始
  126.     Next_Rand();
  127.     unsigned short int left=0,top=0,right=0,bottom=0;
  128.     for(unsigned short int h=0;h<4;h++)
  129.     {
  130.         if(left>Now_Cake[h][0])
  131.         {
  132.             left=Now_Cake[h][0];
  133.         }
  134.         if(right
  135.         {
  136.             right=Now_Cake[h][0];
  137.         }
  138.         if(bottom
  139.         {
  140.             bottom=Now_Cake[h][1];
  141.         }
  142.         Actvie_bottom=bottom+1;
  143.         SetRect(&Active_Rect,FRAME_L+left*30+90,FRAME_T+top*30,FRAME_L+right*30+30+90,FRAME_T+bottom*30+30);
  144.     }
  145.     if(Game_Over())
  146.     {
  147.         if(G_NET)
  148.         {
  149.             if(!Arrive)
  150.             {
  151.                 SendSelect(8);//游戏未完成
  152.             }
  153.             Game_Run();
  154.             return;
  155.         }
  156.         G_start=false;
  157.         G_Over=true;
  158.         Rect_Falling=1000;
  159.         Next_Rand();
  160.         Game_Sound(2);
  161.         KillTimer(hwnd,TIMER_ID);
  162.         InvalidateRect(hwnd,NULL,false);
  163.     }
  164.     else
  165.     {
  166.         InvalidateRect(hwnd,&Active_Rect,false);
  167.         InvalidateRect(hwnd,&N,false);
  168.         Game_Run();
  169.     }
  170. }
  171. bool Gameframe::Game_Over()
  172. {
  173.     if(G_Over)
  174.     {
  175.         return G_Over;
  176.     }
  177.     for(unsigned short int a=0;a<4;a++)
  178.     {
  179.         if(1==Gframe[Now_Cake[a][0]][Now_Cake[a][1]])//判断游戏是否结束(新方块生成时是否已经有方块)
  180.         {
  181.             G_Over=true;
  182.         }
  183.         else
  184.         {
  185.             Gframe[Now_Cake[a][0]][Now_Cake[a][1]]=1;
  186.             Gframe_Color[Now_Cake[a][0]][Now_Cake[a][1]]=Rect_Color;
  187.         }
  188.     }
  189.     if(G_Over)
  190.     {
  191.         return G_Over;
  192.     }
  193.     else
  194.     {
  195.         for(unsigned short int b=0;b<4;b++)
  196.         {
  197.             Gframe[Now_Cake[b][0]][Now_Cake[b][1]]=1;
  198.         }
  199.         return G_Over;
  200.     }
  201.     return G_Over;
  202. }
  203. void Gameframe::Game_Run()//游戏运行
  204. {
  205.     if(G_Over)//游戏结束
  206.     {
  207.         KillTimer(hwnd,TIMER_ID);
  208.         if(G_NET)
  209.         {
  210.             G_NET=false;
  211.             G_start=false;
  212.             SendSelect(11);//通知所有在线人自己的状态
  213.             ::SendMessage(U_hwnd,WM_COMMAND,LBN_SELCHANGE,0);
  214.             if(Arrive)//自己到达或者对方游戏结束
  215.             {
  216.                Game_Sound(7);
  217.             }
  218.             else  
  219.             {
  220.                Game_Sound(2);//对方到达或者自己游戏结束
  221.             }
  222.             InvalidateRect(hwnd,&F,false);
  223.             return;
  224.         }
  225.     }
  226.     else
  227.     {
  228.         if(!G_NET)//单机游戏
  229.         {
  230.             G_Level=Game_Point/1000;
  231.             if(G_Level<10)//游戏是否通关
  232.             {
  233.                 Rect_Falling=1000-G_Level*100;
  234.                 SetTimer(hwnd,TIMER_ID,Rect_Falling,NULL);
  235.             }
  236.             else
  237.             {
  238.                 G_start=false;
  239.                 G_Over=true;
  240.                 Game_Sound(7);
  241.                 Rect_Falling=1000;
  242.                 KillTimer(hwnd,TIMER_ID);
  243.                 InvalidateRect(hwnd,NULL,false);
  244.             }
  245.         }
  246.         else
  247.         {
  248.             SetTimer(hwnd,TIMER_ID,NET_SPEED,NULL);//对战运行速度
  249.         }
  250.     }
  251. }
  252. void Gameframe::Game_Stop()//暂停
  253. {
  254.     G_Stop=true;
  255.     KillTimer(hwnd,TIMER_ID);
  256. }
  257. bool Gameframe::Game_Move(int i)
  258. {
  259.     Move_temp=i;
  260.     if(Game_Active(2))
  261.     {
  262.        if(1==i)
  263.        {
  264.           Active_Rect.right=Active_Rect.right+i*30;
  265.           InvalidateRect(hwnd,&Active_Rect,false);
  266.           Active_Rect.left=Active_Rect.left+i*30;
  267.        }
  268.        else
  269.        {
  270.           Active_Rect.left=Active_Rect.left+i*30;
  271.           InvalidateRect(hwnd,&Active_Rect,false);
  272.           Active_Rect.right=Active_Rect.right+i*30;
  273.        }
  274.        return true;
  275.     }
  276.     else
  277.     {
  278.         return false;
  279.     }
  280. }
  281. void Gameframe::Game_Down()//下落
  282. {
  283.     if(G_Over)
  284.     {
  285.         Game_Run();
  286.     }
  287.     if(Down<19)
  288.     {
  289.         Down=Down+1;//变形时,需要使用纵坐标
  290.     }
  291.     else
  292.     {
  293.         Down=0;//变形时,需要使用纵坐标
  294.     }
  295.    if(Game_Active(1))
  296.    {
  297.       Down_end=true;// 是否可以连续下落和重绘时是否需要刷新下一个方块
  298.       Active_Rect.bottom=Active_Rect.bottom+30;//在原来方块基础上增加下一行更新面积
  299.       Actvie_bottom=Actvie_bottom+1;
  300.       if(!Space_on)
  301.       {
  302.           InvalidateRect(hwnd,&Active_Rect,false);
  303.       }
  304.       Active_Rect.top=Active_Rect.top+30;//刷新后将上方也增加一行
  305.    }
  306.    else
  307.    {
  308.        Game_Sound(4);
  309.        if(G_NET)
  310.        {
  311.            SendSelect(5);
  312.        }
  313.        Space_on=false;
  314.        if(!Game_DelRect())//消行算分。
  315.        {
  316.           InvalidateRect(hwnd,&F,false);
  317.        }
  318.        Down_end=false;//不能下落了。
  319.        Game_Start();//重新开始生成方块。
  320.    }
  321. }
  322. void Gameframe::Game_Change()//变形
  323. {
  324.     Frame_B=Frame_B+1;
  325.     if(6==Frame_A||5==Frame_A||2==Frame_A)//4种类型的方块
  326.     {
  327.         if(Frame_B>3)
  328.         {
  329.             Frame_B=0;
  330.         }
  331.     }
  332.     else
  333.     {
  334.         if(Frame_B>1)
  335.         {
  336.             Frame_B=0;
  337.         }
  338.     }
  339.     if(Game_Active(3))//变形是否成功
  340.     {
  341.         Game_Sound(6);
  342.         InvalidateRect(hwnd,&Active_Rect,false);
  343.         short int left=0,top=0,right=0,bottom=0,k=0;
  344.         for(short int h=0;h<4;h++)
  345.         {
  346.             if(left>Now_Cake[h][k])
  347.             {
  348.                 left=Now_Cake[h][k];
  349.             }
  350.             if(right
  351.             {
  352.                 right=Now_Cake[h][k];
  353.             }
  354.             if(bottom
  355.             {
  356.                 bottom=Now_Cake[h][k+1];
  357.             }
  358.             if(top>Now_Cake[h][k+1])
  359.             {
  360.                 top=Now_Cake[h][k+1];
  361.             }
  362.         }
  363.         Actvie_bottom=bottom+1;
  364.         SetRect(&Active_Rect,FRAME_L+left*30,FRAME_T+top*30,FRAME_L+right*30+30,FRAME_T+bottom*30+30);
  365.         InvalidateRect(hwnd,&Active_Rect,false);
  366.     }
  367.     else
  368.     {
  369.         if(6==Frame_A||5==Frame_A||2==Frame_A)//变形失败,返回原来的样子
  370.         {
  371.             if(Frame_B>=1)
  372.             {
  373.                 Frame_B=Frame_B-1;
  374.             }
  375.             else
  376.             {
  377.                 Frame_B=Frame_B+3;
  378.             }
  379.         }
  380.         else
  381.         {
  382.             if(Frame_B>=1)
  383.             {
  384.                 Frame_B=Frame_B-1;
  385.             }
  386.             else
  387.             {
  388.                 Frame_B=Frame_B+1;
  389.             }
  390.         }
  391.         InvalidateRect(hwnd,&F,false);
  392.     }
  393. }
  394. bool Gameframe::Game_DelRect()
  395. {
  396.     int del=0,Count=0;
  397.     bool re=false;
  398.     for(short int a=19;a>=Top;a--)
  399.     {
  400.         for(short int b=0;b<10;b++)
  401.         {
  402.             if(1==Gframe[b][a])
  403.             {
  404.                 del=del+1;
  405.             }
  406.         }
  407.         if(10==del)
  408.         {
  409.             Count=Count+1;
  410.             for(a;a>=0;a--)
  411.             {
  412.                 if(0==a)//只要有消行。那么最顶层一定是空的
  413.                 {
  414.                     for(short int d=0;d<10;d++)
  415.                     {
  416.                         Gframe[d][a]=false;
  417.                         Gframe_Color[d][a]=0;
  418.                     }
  419.                 }
  420.                 else
  421.                 {
  422.                     for(short int c=0;c<10;c++)
  423.                     {
  424.                         Gframe[c][a]=Gframe[c][a-1];
  425.                         Gframe_Color[c][a]=Gframe_Color[c][a-1];
  426.                     }
  427.                 }
  428.             }
  429.             a=20;//不能等于十九。因为要进行a--操作
  430.             Top=Top+1;
  431.         }
  432.         del=0;
  433.     }
  434.     switch(Count)
  435.     {
  436.     case 1:
  437.         re=true;
  438.         Game_Sound(5);
  439.         Game_Point=Game_Point+100;
  440.         InvalidateRect(hwnd,NULL,false);//写在外面在游戏结束时看不到下一块方块
  441.         break;
  442.     case 2:
  443.         re=true;
  444.         Game_Sound(5);
  445.         Game_Point=Game_Point+300;
  446.         InvalidateRect(hwnd,NULL,false);
  447.         break;
  448.     case 3:
  449.         re=true;
  450.         Game_Sound(5);
  451.         Game_Point=Game_Point+500;
  452.         InvalidateRect(hwnd,NULL,false);
  453.         break;
  454.     case 4:
  455.         re=true;
  456.         Game_Sound(5);
  457.         Game_Point=Game_Point+800;
  458.         InvalidateRect(hwnd,NULL,false);
  459.         break;
  460.     default:
  461.         break;
  462.     }
  463.     if(G_NET)
  464.     {
  465.         if(Count>0)
  466.         {
  467.             SendInfo[1]=Count;//消了几行
  468.             SendSelect(6);
  469.             if(Game_Point>=Aim)
  470.             {
  471.                 SendSelect(7);
  472.             }
  473.         }
  474.     }
  475.     return re;
  476. }
  477. void Gameframe::Game_Restart()
  478. {
  479.     /**********初始化界面为0,表示没有方块*********/
  480.     for(unsigned short int a1=0;a1<20;a1++)
  481.     {
  482.         for(unsigned short int b1=0;b1<10;b1++)
  483.         {
  484.             Gframe[b1][a1]=0;//表示没有方块
  485.             Gframe_Color[b1][a1]=0;//游戏颜色都初始化为0
  486.             Child_Frame[b1][a1]=0;
  487.         }
  488.     }
  489.     /**********初始化当前活动方块位置,表示没有方块*********/
  490.     for(unsigned short int j=0;j<4;j++)
  491.     {
  492.         for(unsigned short int k=0;k<2;k++)
  493.         {
  494.             Now_Cake[j][k]=0;
  495.             Old_Cake[j][k]=0;
  496.         }
  497.     }
  498.     /******初始化第一个NEXT和主界面的第一个方块********/
  499.     struct _timeb timebuffer;
  500.     _ftime(&timebuffer);
  501.     unsigned short int tem=timebuffer.millitm;
  502.     unsigned short int a=tem%7;
  503.     short int b=0;
  504.     srand(tem);
  505.     if(6==a||5==a||2==a)
  506.     {
  507.         b=timebuffer.millitm%4;
  508.     }
  509.     else
  510.     {
  511.         b=timebuffer.millitm%2;
  512.     }
  513.     Frame_A=Next_A=a;
  514.     Frame_B=Next_B=b;
  515.     Rect_Color=Rect_Color_N=rand()%7;
  516.     /************************************************/
  517.     Down_end=true;//默认可以下落
  518.     Rect_Falling=1000;//游戏下落时间
  519.     G_start=false;//游戏还没开始
  520.     G_Over=false;//游戏未结束
  521.     G_Stop=false;//游戏未暂停
  522.     Arrive=false;//没有达到目标
  523.     Top=19;//默认为方块的最底层
  524.     Game_Point=0;//分数起点为0
  525.     Child_Point=0;//对方分数起点为0
  526.     Down=0;//下降格数
  527.     Move=0;//移动格数
  528.     G_Level=0;//默认是0级
  529.     Space_on=false;//默认不按下空格键
  530.     InvalidateRect(hwnd,NULL,false);
  531. }
  532. bool Gameframe::Game_Active(int Event)
  533. {
  534.   return ture;
  535. }

你可能感兴趣的:(准新手 c++ win32 API实现方块联机游戏历程)