cwin32API实现方块联机游戏历程.doc_第1页
cwin32API实现方块联机游戏历程.doc_第2页
cwin32API实现方块联机游戏历程.doc_第3页
cwin32API实现方块联机游戏历程.doc_第4页
cwin32API实现方块联机游戏历程.doc_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

先简单介绍下自己的情况,2006年普通大专院校毕业,毕业后到了北京参加软件测试的培训,目前做ASP.NET网站安全等方面的测试。很多人都说技术不好才去做测试的,很不幸言中了,我当时我的情况确实是这样的,这大概也是很多做测试的朋友心中的一个老梗。即使工作了,心中的梦魇一直没能除去,所以决定试试自己到底能不能写点东西。在工作期间,自学SQLSERVER+ASP.NET 在工作一年后正式参与网站开发。 写俄罗斯方块联机游戏想法,源于到北京后的培训经历,那时候的老师是一个在华为经历几年开发经验和测试经验的高手,当他告诉我说:“听说你号称学过C+的时候”,我心里其实蛮惭愧的,因为确实不懂。从此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的程序,虽然只是个小游戏,但也给了我一些信心和鼓舞,希望有机会能正式加入程序员阵营中来,目前职位还是测试工作,想这下一步的开发方向该怎么走。希望各位同仁多多指教,给点建议。多谢啦。 下载地址:/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_yclass Gameframe:public GameNetpublic: 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_Path100;/游戏路径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 intNext_B;/下一个方块具体形状 short int Frame_A;/当前方块类型 short int Frame_B;/当前方块具体形状 short int Move;/移动格子数 short int Down;/下降个数 short int Now_Cake42;/新方块 0横坐标 1纵坐标 short int Old_Cake42;/旧方块 0横坐标 1纵坐标 short int Top;/有方块的最高点 bool Gframe1020;/10横坐标 20 纵坐标 unsigned short int G_Level; int Rect_Falling; /下落时间差 short int Gframe_Color1020;/主游戏方块颜色 short int Rect_Color;/当前方块颜色 short int Rect_Color_N;/下一个方块颜色 COLORREF G_BasicColor7;/方块颜色基础 bool Game_Active(int Event);/方块事件处理 bool Game_DelRect();/消行算法private:;#endif Gamefrme.cpp#include Gameframe.h/ Gameframe Class/int Move_temp;extern HINSTANCE h_inst;extern HWND hwnd;extern HWNDU_hwnd;/用户列表void Gameframe:Draw_Next(HDC hDC,HWND hwnd,HBRUSH G_brush)/ 重绘下一个方块框架主游戏框架+内容 N.left=Total.left; FillRect(hDC,&N,G_brush); FillRect(hDC,&Total,G_brush); SetDCBrushColor(hDC,G_BasicColorRect_Color_N); for(int c=0;c4;c+) for(int d=0;d4;d+) if(1=squ.NextframeNext_ANext_Bdc) 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); FillRect(hDC,&re,G_brush); char szChar25; sprintf(szChar,%d VS %d,Game_Point,Child_Point); unsigned short int count=0,i=0; while(szChari != 0) count+; i+; TextOut(hDC,NEXT_L+20,NEXT_T+185,szChar,count);void Gameframe:Draw_Frame(HDC hDC,HWND hwnd,HBRUSH G_brush)/主游戏框架+内容 SetDCBrushColor(hDC,RGB(0,0,0); FillRect(hDC,&F,G_brush); for(unsigned short int o=0;o10;o+) for(unsigned short int p=0;p9) G_Level=1; TextOut(hDC,FRAME_L+100,FRAME_T+270,通关了!厉害,strlen( ); else if(!Arrive) TextOut(hDC,FRAME_L+100,FRAME_T+270,GAME OVER,strlen(GAME OVER); else TextOut(hDC,FRAME_L+100,FRAME_T+270,YOURE WINNER,strlen(YOURE WINNER); void Gameframe:Draw_Message(HDC hDC,HWND hwnd,HBRUSH G_brush) SetDCBrushColor(hDC,RGB(255,255,255); SetTextColor(hDC,RGB(0,0,0); FillRect(hDC,&Info,G_brush); DrawText(hDC,InfoChar,strlen(InfoChar),&Info,DT_LEFT);void Gameframe:Draw_Child(HDC hDC,HWND hwnd,HBRUSH G_brush) SetDCBrushColor(hDC,RGB(0,0,0); SetRect(&re,0,0,200,400); FillRect(hDC,&re,G_brush); for(unsigned short int o=0;o10;o+) for(unsigned short intp=0;pGame_Restart();Gameframe:Gameframe() squ.Square();void Gameframe:Game_Start() /游戏开始 Next_Rand(); unsigned short int left=0,top=0,right=0,bottom=0; for(unsigned short int h=0;hNow_Cakeh0) left=Now_Cakeh0; if(rightNow_Cakeh0) right=Now_Cakeh0; if(bottomNow_Cakeh1) bottom=Now_Cakeh1; Actvie_bottom=bottom+1; SetRect(&Active_Rect,FRAME_L+left*30+90,FRAME_T+top*30,FRAME_L+right*30+30+90,FRAME_T+bottom*30+30); if(Game_Over() if(G_NET) if(!Arrive) SendSelect(8);/游戏未完成 Game_Run(); return; G_start=false; G_Over=true; Rect_Falling=1000; Next_Rand(); Game_Sound(2); KillTimer(hwnd,TIMER_ID); InvalidateRect(hwnd,NULL,false); else InvalidateRect(hwnd,&Active_Rect,false); InvalidateRect(hwnd,&N,false); Game_Run(); bool Gameframe:Game_Over() if(G_Over) return G_Over; for(unsigned short int a=0;a4;a+) if(1=GframeNow_Cakea0Now_Cakea1)/判断游戏是否结束(新方块生成时是否已经有方块) G_Over=true; else GframeNow_Cakea0Now_Cakea1=1; Gframe_ColorNow_Cakea0Now_Cakea1=Rect_Color; if(G_Over) return G_Over; else for(unsigned short int b=0;b4;b+) GframeNow_Cakeb0Now_Cakeb1=1; return G_Over; return G_Over;void Gameframe:Game_Run()/游戏运行 if(G_Over)/游戏结束 KillTimer(hwnd,TIMER_ID); if(G_NET) G_NET=false; G_start=false; SendSelect(11);/通知所有在线人自己的状态 :SendMessage(U_hwnd,WM_COMMAND,LBN_SELCHANGE,0); if(Arrive)/自己到达或者对方游戏结束 Game_Sound(7); else Game_Sound(2);/对方到达或者自己游戏结束 InvalidateRect(hwnd,&F,false); return; else if(!G_NET)/单机游戏 G_Level=Game_Point/1000; if(G_Level10)/游戏是否通关 Rect_Falling=1000-G_Level*100; SetTimer(hwnd,TIMER_ID,Rect_Falling,NULL); else G_start=false; G_Over=true; Game_Sound(7); Rect_Falling=1000; KillTimer(hwnd,TIMER_ID); InvalidateRect(hwnd,NULL,false); else SetTimer(hwnd,TIMER_ID,NET_SPEED,NULL);/对战运行速度 void Gameframe:Game_Stop()/暂停 G_Stop=true; KillTimer(hwnd,TIMER_ID);bool Gameframe:Game_Move(int i) Move_temp=i;if(Game_Active(2) if(1=i) Active_Rect.right=Active_Rect.right+i*30; InvalidateRect(hwnd,&Active_Rect,false); Active_Rect.left=Active_Rect.left+i*30; else Active_Rect.left=Active_Rect.left+i*30; InvalidateRect(hwnd,&Active_Rect,false); Active_Rect.right=Active_Rect.right+i*30; return true; else return false; void Gameframe:Game_Down()/下落 if(G_Over) Game_Run(); if(Down3) Frame_B=0; else if(Frame_B1) Frame_B=0; if(Game_Active(3)/变形是否成功 Game_Sound(6); InvalidateRect(hwnd,&Active_Rect,false); short int left=0,top=0,right=0,bottom=0,k=0; for(short int h=0;hNow_Cakehk) left=Now_Cakehk; if(rightNow_Cakehk) right=Now_Cakehk; if(bottomNow_Cakehk+1) top=Now_Cakehk+1; Actvie_bottom=bottom+1; SetRect(&Active_Rect,FRAME_L+left*30,FRAME_T+top*30,FRAME_L+right*30+30,FRAME_T+bottom*30+30); InvalidateRect(hwnd,&Active_Rect,false); else if(6=Frame_A|5=Frame_A|2=Frame_A)/变形失败,返回原来的样子 if(Frame_B=1) Frame_B=Frame_B-1; else Frame_B=Frame_B+3; else if(Frame_B=1) Frame_B=Frame_B-1; else Frame_B=Frame_B+1; InvalidateRect(hwnd,&F,false); bool Gameframe:Game_DelRect() int del=0,Count=0; bool re=false; for(short int a=19;a=Top;a-) for(short int b=0;b=0;a-) if(0=a)/只要有消行。那么最顶层一定是空的 for(short int d=0;d10;d+) Gframeda=false; Gframe_Colorda=0; else for(short int c=0;c0) SendInfo1=Count;/消了几行 SendSelect(6);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论