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

本文记录了作者从零开始使用C++和Win32 API开发俄罗斯方块游戏的过程,从窗口创建到游戏运行机制,再到游戏算法实现,详细描述了每个步骤和遇到的挑战。通过不断实验和测试,最终完成了单机版和网络版的联机功能,体现了编程思维和解决问题的能力。

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

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

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

实际过程:

      

       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.youkuaiyun.com/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 Ga
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值