写俄罗斯方块联机游戏想法,源于到北京后的培训经历,那时候的老师是一个在华为经历几年开发经验和测试经验的高手,当他告诉我说:“听说你号称学过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
- #include "GameNet.h"
- #ifndef _GAMEFRAME_H_
- #define _GAMEFRAME_H_
- using namespace std;
- #define SingleRect 30 //单个方块大小
- #define FRAME_L 15 //主界面的起点坐标 L
- #define FRAME_T 15 //主界面的起点坐标 T
- #define NEXT_L SingleRect*10+FRAME_L+15 //下一个方块的起点座标 L
- #define NEXT_T FRAME_T //下一个方块的起点座标 T
- #define MAIN_SIZE_R SingleRect*10+FRAME_L //主界面x_x
- #define MAIN_SIZE_B SingleRect*20+FRAME_T //主界面y_y
- #define NEXT_SIZE_R SingleRect*4+NEXT_L+20 //下一个方块x_x
- #define NEXT_SIZE_B SingleRect*4+NEXT_T+20 //下一个方块y_y
- class Gameframe:public GameNet
- {
- public:
- Gameframe();
- virtual ~Gameframe();
- void Draw_Frame(HDC hDC,HWND hwnd,HBRUSH G_brush);//重绘主框架
- void Draw_Next(HDC hDC,HWND hwnd,HBRUSH G_brush);////重绘下一个方块框架
- void Draw_Message(HDC hDC,HWND hwnd,HBRUSH G_brush);//重绘下一个方块框架
- void Draw_Child(HDC hDC,HWND hwnd,HBRUSH G_brush);//重绘子窗口
- void Game_Start();//开始游戏
- bool G_Stop;//游戏是否暂停
- bool Game_Over();//判断游戏是否结束
- void Game_Run();//开始运行,设定下落时间
- void Game_Down();//方块下落
- void Game_Change();//方块变形
- bool Game_Move(int i);//方块移动
- void Game_Stop();
- void Game_Restart();
- void Game_Sound(unsigned short int sound);
- bool Down_end;
- bool Space_on;
- char G_Path[100];//游戏路径
- protected:
- void Next_Rand();//生成下一个方块
- RECT N;//下一个方块界面
- RECT F;//主界面
- RECT Active_Rect;//方块活动界面
- RECT Total;//得分界面
- RECT re;//
- unsigned short int Actvie_bottom;//活动方块的最下面
- Square squ;//定义一个方块的对象
- short int Next_A;//下一个方块类型
- short int Next_B;//下一个方块具体形状
- short int Frame_A;//当前方块类型
- short int Frame_B;//当前方块具体形状
- short int Move;//移动格子数
- short int Down;//下降个数
- short int Now_Cake[4][2];//新方块 0横坐标 1纵坐标
- short int Old_Cake[4][2];//旧方块 0横坐标 1纵坐标
- short int Top;//有方块的最高点
- bool Gframe[10][20];//10横坐标 20 纵坐标
- unsigned short int G_Level;
- int Rect_Falling; //下落时间差
- short int Gframe_Color[10][20];//主游戏方块颜色
- short int Rect_Color;//当前方块颜色
- short int Rect_Color_N;//下一个方块颜色
- COLORREF G_BasicColor[7];//方块颜色基础
- bool Ga