




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、MFC版俄罗斯方块2010-01-11 21:17MFC版俄罗斯方块总算完成了,足足花了我两天时间,其间出现过好多问题,后来都被一一化解, 最头疼的是昨天晚上那个Bug把我头都弄大了,找了一晚上都没找出来,幸亏第二天脑子清醒才发现问题,要不然我 真的很难找到一条让自己不崩溃的理由。呵呵,还好顶住了,任务也算顺利完成了。我写的这个俄罗斯方块游戏功能 虽然比较简单,界面做的也很普通,但是从设计到实现基本上是用自己的算法实现的,虽然在程序的封装性和模 块化上面做的不够好,东补西凑也算凑合吧。总归一句话,不容易啊!闲话不多说了,下面我介绍一下俄罗斯方块的设计思路和流程以及在编码过程中遇到的一些问 题。
2、在写俄罗斯方块之前我对这个经典的小游戏进行了策略分析,并大体总结出了它的功能需求。下面是我当时记录的游戏设计的功能需求:图形界面布局(长方形主框,图形预览,score,Level)各种Shape的数据结构的存储和随机生成图形界面的绘制以及各控件显示(主图形、预览图形显示、score、level、游戏说明)时钟控制图形更新(主图的下降)图形的变换控制:11控制键响应边界控制和图形的保存(Map2741)消格,得分,升级图形变化控制策略:要求对Shape对应四个点分别进行如下判断“1”代表有方格“0”无下边有方格停止并保存超出左右边界以及左右格有值(1)不能移动在变形之前先判断一下是否满足前三条,
3、满足可以变形,不满足变形失败简单的分析之后就开工了,第一步就是简单的托下控件,几分钟就KO 了,然后就是对Shape数据结 构的分析,网上搜了一下有7类19种,于是在OneNote里面将所有可能都描绘出来了如下:(0.0,0 .o-.a.Q.a.o)(D.OAO.-1.2.-V2(0.0.-l.-1.0r0rl.-l)_口中(OX.O.O.O.Z.O.O)2.0.0.0.0,0.0.030.0.2.0.O.O.O.Q)(U.0r-0,0.-1.2.0.0)函zd(D.O.D.a.-Z.l.D.O)(O.O.-O.O.-l.Z.O.l)(a.o.D.o.a.o.i.-i)(0r0,l1l10,0
4、1i10)H.i.o.o.c.o.a.oj(o.o.i.1.0,0.0.0)(ij.a.a.-o.o.o.o(O.O.-O.O/l.-l.-O.O)左边是7种图形,右边是其相对正方形图形的偏移量,正方形没有变种,左边其它三类图形有2个变 种,右边三类图形有4个变种,加起来正好19种类型,将这些相对正方形偏移得来的图形记录到二维数组Shape198当中,然后就是设法让这些图形随机生成,简单,rand()%19即可,这样第二部就完成了。接下来就是想办法将图形绘制出来了,开始是基于过程,写了一大堆代码来实现这个功能,后来发现绘制出来的图形还要被擦除,这两个功 能用到的代码基本上是一样的,于是就自己定
5、义了一个m_DrawImage的成员函数来完成图形的绘制功能。主图形完 了之后,开始考虑如何实现预览功能,发现预览的图形不需要考虑位置的移动,并重载了一下m_DrawImage实现了 对预览图形的绘制。接下来就是想办法让图形动起来了,想到了用时钟SetTimer让它隔一段时间位置下落一定距 离,这里关键是要考虑到如何将之前的图形擦除,怎么办呢?其实只需将之前绘制的图形保存,并用和背景颜色一致画刷绘制就可实现擦除功能。第五步就是实现图形的变换控制了,注意一点对话框程序不能直接用WM_KEYDOWN消息 来实现,要用PreTranslateMessage代替。因为在对话框程序中,某些特定的消息,例
6、如按键消息,它们被Windows 内部的对话框过程处理了(即在基类中完成了处理,可以查看MFC的源代码),或者被发送给子控件(获取焦点 的子控件)进行处理,所以我们在对话框类中就捕获不到按键的消息了。比较伤脑筋的就是第六步了,程序写到这里 就要考虑如何保存之前的数据以及如何防止方块出界的问题了,问题变得越来越具体,对数据的要求也越来越精确,这一步我用GetClientRect(&rect)测量了主窗口的长和宽并用数组Map2741将其进行了保存。在考虑如何保 存方块位置以及边界控制的过程中,为题就出现了,我之前想只用到一个点坐标m_CurPos记录左上角一个方块 的位置,然后想根据其它方块和它
7、相连的关系和偏移量Shape的关系来却定所有定的确切位置,在实现过程中发现这 样好繁琐,每一个点的表示都有好长一串代码,我才意识到偷懒是不行的,还是必须用四个点来记录每一个方块的 位置,于是我用PointArray4分别记录了四个点的坐标位置,这样之后问题就明朗了,一个一个点去考虑,比起 四个点一起考虑要容易的多,这也是化抽象为具体,分而治之这种最简单而又最实用的方法的强大威力的的再一次 证实。最后就是消格,得分,升级的问题了,有了前面的基础这些问题也都很快沿刃而解了。在第6步的过程中也产生了最让我头疼的Bug,后来想想这根本就不算是问题,都怪自己粗心大意, 害自己白忙活一晚上,最开始我本来是
8、对的Map2741这个数组横坐标对应x值,纵坐标对应y值,不知道突然哪 根筋不对了,想着要把它改成Map4127,41行,27列,对啊,幸亏及时纠正,没想到这一改差点把我整崩溃了。本 来这么简单的问题不应该看不出来,但是有时候啊,人的那个脑袋就是容易产生固定化思维模式,这也是阻碍很多人 进步的原因之所在。人思维的缺陷啊!不能怪我O(C_C)O哈哈照例贴一下主要的代码,一是为了自己以后使用方便,二来和大家探讨交流一下,其中还有很多不合 理的地方,路过的朋友可以指正一下。class CTetrisDlg : public CDialogpublic:void m_DrawImage(int ID,
9、 COLORREF clr, int x,int y, int shape);CTetrisDlg(CWnd* pParent = NULL);/ standard constructorvoid m_DrawImage(int ID,COLORREF clr,CPoint point,int shape);public:virtual BOOL PreTranslateMessage(MSG* pMsg);protected:virtual void DoDataExchange(CDataExchange* pDX);/ DDX/DDV support/AFX_VIRTUALprotect
10、ed:virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);afx_msg void OnTimer(UINT nIDEvent);private:DWORD State;int Score;CPoint PointArray4;bool Map2741
11、;int Shape198;int m_OldNextShape;int m_NextShape;int m_ioldshape;CPoint m_poldpos;int size;CPoint m_pcurpos;int m_CurShape;BOOL CTetrisApp:InitInstance()CTetrisDlg dlg;m_pMainWnd = &dlg;SetDialogBkColor(RGB(0,0,0),RGB(0,255,0);/ 设置对话框颜色和字体 int nResponse = dlg.DoModal();CTetrisDlg:CTetrisDlg(CWnd* pP
12、arent /*=NULL*/):CDialog(CTetrisDlg:IDD, pParent)srand(time(NULL);/ 设置随机种子m_CurShape=rand()%19;/初始化方块类型m_pcurpos.x=120;/方块当前位置m_pcurpos.y=0;m_NextShape=rand()%19;m_OldNextShape=m_NextShape;m_ioldshape=m_CurShape;m_poldpos=m_pcurpos;size=10;/方块大小Score=0;State=0;m_hIcon = AfxGetApp()-LoadIcon(IDR_MAIN
13、FRAME);BOOL CTetrisDlg:OnInitDialog()SetTimer(1,500,NULL);GetDlgItem(IDC_STATIC_SCORE)-SetWindowText(0);GetDlgItem(IDC_STATIC_LEVEL)-SetWindowText(Level 1);/初始化Shape数组【注意成员变量不能在定义的时候初始化,同时在构造函里也不能实现一 次性赋值,于是想到用等量替换代替手动赋值!】 int Shape1198= 0,0,0,0,0,0,0,0, 0,0,0,0,-1,2,-1,2,0,0,-1,-1,0,0,1,-1,0,0,0,0,
14、0,2,0,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,-1,2,0,1,0,0,0,0,0,0,1,-1,0,0,1,1,0,0,0,0,-1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,-1,1,0,0,0,0,0,0,0,0,0,0,-1,-1,0,0,0,0,0,0,0,0,1,-1,0,0,0,0,-1,2,0,0,0,0,0,0,0,0,-2,-1,0,0,1,-2,0,0,0,0,0,0,0,0,-2,1,0,0 ;memcpy(Shape,Shape1,sizeof(int)*19*8);f
15、or(int i=0;i27;i+)for(int j=0;j41;j+)Mapij=0;return TRUE; / return TRUE unless you set the focus to a control void CTetrisDlg:OnPaint()m_DrawImage(IDC_STATIC_MAIN,RGB(0,0,0),m_poldpos,m_ioldshape);m_DrawImage(IDC_STATIC_PRE,RGB(0,0,0),50,50,m_OldNextShape);m_poldpos=m_pcurpos;/记录当前形状和位置m_ioldshape=m
16、_CurShape;m_OldNextShape=m_NextShape;m_DrawImage(IDC_STATIC_MAIN,RGB(0,255,0),m_pcurpos,m_CurShape);m_DrawImage(IDC_STATIC_PRE,RGB(0,255,0),50,50,m_NextShape);CDialog:OnPaint();void CTetrisDlg:OnTimer(UINT nIDEvent)int i;switch(nIDEvent)case 1:/Timer1触底判断,并产生新的方块for(i=0;i4;i+)if(PointArrayi.y=40*siz
17、e |MapPointArrayi.x/sizePointArrayi.y/size+1=1) for(int j=0;j=4)m_pcurpos.y+=size;Invalidate();break;case 2:/Timer2用来实现暂停功能,不过效果不太理想。Sleep(8000);break;CDialog:OnTimer(nIDEvent);void CTetrisDlg:m_DrawImage(int ID, COLORREF clr, CPoint point, int shape)CWnd* pWnd=GetDlgItem(ID); / 预览句柄CDC* pControlDC=
18、pWnd-GetDC();pWnd-Invalidate();pWnd-UpdateWindow();CBrush brush(clr);/创建背景色笔刷pControlDC-SelectObject(&brush);/记录当前4个方格的位置PointArray0.x=point.x+Shapeshape0*size;PointArray0.y=point.y+Shapeshape1*size;PointArray1.x=point.x+Shapeshape2*size;PointArray1.y=point.y+Shapeshape3*size+size;PointArray2.x=poin
19、t.x+Shapeshape4*size+size;PointArray2.y=point.y+Shapeshape5*size;PointArray3.x=point.x+Shapeshape6*size+size;PointArray3.y=point.y+Shapeshape7*size+size;/画方块pControlDC-Rectangle(PointArray0.x,PointArray0.y,PointArray0.x+size,PointArray0.y+size);pControlDC-Rectangle(PointArray1.x,PointArray1.y,PointA
20、rray1.x+size,PointArray1.y+size);pControlDC-Rectangle(PointArray2.x,PointArray2.y,PointArray2.x+size,PointArray2.y+size);pControlDC-Rectangle(PointArray3.x,PointArray3.y,PointArray3.x+size,PointArray3.y+size);for(int i=0;i41;i+)/消格for(int j=0;jSelectObject(&brush1);pWnd-Invalidate();pWnd-UpdateWindo
21、w();int k;for(k=i;k=1;k)for(int m=0;mRectangle(m*size,k*size,m*size+size,k*size+size );brush1.DeleteObject();Score+=100;/加分char TemScore10;itoa(Score,TemScore,10);GetDlgItem(IDC_STATIC_SCORE)-SetWindowText(TemScore);if(Score%1000=0)/1000 分升级 char TemLevel10;char TemLevel210;strcpy(TemLevel,Level );i
22、toa(Score/100+1),TemLevel2,10);strcat(TemLevel,TemLevel2);GetDlgItem(IDC_STATIC_LEVEL)-SetWindowText(TemLevel);for(i=0;i27;i+)/画方格图 Map2741for(int j=0;jRectangle(i*size,j*size,(i+1)*size,(j+1)*size);brush.DeleteObject();pWnd-ReleaseDC(pControlDC);/预览图形的绘制函数void CTetrisDlg:m_DrawImage(int ID, COLORRE
23、F clr, int x, int y, int shape)CWnd* pWnd=GetDlgItem(ID);CDC* pControlDC=pWnd-GetDC();CRect rect;CPoint point;pWnd-GetClientRect(&rect);point.x =rect.left+x;point.y=rect.top+y;pWnd-Invalidate();pWnd-UpdateWindow();CBrush brush(clr);/创建背景色笔刷pControlDC-SelectObject(&brush);pControlDC-Rectangle(point.x
24、+Shapeshape0*size,point.y+Shapeshape1*size, point.x+Shapeshape0*size+size,point.y+Shapeshape1*size+size);pControlDC-Rectangle(point.x+Shapeshape2*size,point.y+Shapeshape3*size+ size,point.x+Shapeshape2*size+size,point.y+Shapeshape3*size+2*size);pControlDC-Rectangle(point.x+Shapeshape4*size+size,point.y+Shapeshape5*size,point.x+Shapeshape4*size+2*size,point.y+Shapeshape5*s
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 广西钦州市第四中学2024−2025学年高二下学期期中数学试卷含答案
- 亲子教育机构品牌加盟合作合同
- 智能建筑光伏发电项目设备租赁与技术研发合同
- 房地产租赁市场拓展与佣金收益分配合同
- 污水处理厂委托管理及污水处理能力提升协议
- 能源产业政策研究与执行合同
- 智能节水控制系统租赁及升级改造合同
- 网红甜品店全国区域独家代理权合作协议
- 高层办公楼电梯全面检修、保养与安全保障协议
- 河南省驻马店市驿城区驻马店高级中学2024-2025学年高二下学期4月月考英语试卷
- 华为结构面试题及答案
- 【MOOC期末】《大学体育射箭》(东南大学)中国大学慕课答案
- 中医适宜技术-中药热奄包
- 2023年全国职业院校技能大赛-老年护理与保健赛项规程
- MOOC 财政学-浙江财经大学 中国大学慕课答案
- 中医儿科学:小儿生长发育
- 重庆邮电大学本科毕业设计(论文)参考模板-2020版
- 泌尿系结石医学PPT课件
- 《现代汉语修辞》PPT课件(完整版)
- CRH380B动车组电气系统综述综述
- 作业准备验证及停工后验证规定
评论
0/150
提交评论